2011-12-01 16 views
6

Jestem początkującym początkującym programistą Scala i chciałbym uzyskać poradę, jak postępować w implementacji, która wydaje się, że można to zrobić za pomocą funkcji zwracającej funkcję lub funkcji częściowej. Czytałem wszystkie powiązane posty, które mogłem znaleźć (patrz bottom of question), ale te wydają się obejmować techniczne szczegóły korzystania z PartialFunction lub konwertowania jednego do drugiego; Szukam odpowiedzi typu "jeśli okoliczności są X, Y, Z, a następnie użyj A else B, ale także rozważ C".Scala: wybieranie zwracania funkcji Option versus PartialFunction

Mój przykład użycia to wyszukiwanie ścieżki między lokalizacjami przy użyciu biblioteki wyszukiwaczy ścieżek. Powiedzmy, że lokalizacje są typu L, ścieżka była typu P, a pożądany wynik wyszukiwania ścieżki to Iterable[P]. Wynik wyszukiwania łatki powinien zostać złożony poprzez zapytanie wszystkich lokalizatorów ścieżek (w czymś takim, jak mapy Google mogą to być: Rower, Samochód, Spacer, Metra itd.) W celu uzyskania sugestii dotyczących ścieżki, które mogą lub nie mogą być zdefiniowane dla określonego początku/para końcowej lokalizacji.

Nie wydają się być dwa sposoby, aby przejść na ten temat:

(a) zdefiniowanie finder ścieżki jako f: (L,L) => Option[P] a następnie uzyskać wynik poprzez coś jak finders.map(_.apply(l1,l2)).filter(_.isDefined).map(_.get)

(b) zdefiniowanie finder ścieżki jako f: PartialFunction[(L,L),P] and then get the result via something like finders.filter (_.isDefined ((l1, l2))) .map (_.apply ((l1, l2))) `

Wygląda na to, że użycie funkcji zwracającej Option[P] pozwoliłoby uniknąć podwójnej oceny wyników, więc w przypadku kosztownych obliczeń może to być lepsze, o ile nie buforuje wyników. Wydaje się również, że używając Option można mieć dowolną sygnaturę wejściową, podczas gdy PartialFunction oczekuje pojedynczego argumentu. Ale szczególnie interesuje mnie słuchanie od kogoś z praktycznym doświadczeniem na temat mniej bezpośrednich, bardziej "obszernych" rozważań, takich jak interakcja z biblioteką Scala. Czy użycie opcji PartialFunction przyniesie znaczne korzyści w udostępnieniu niektórych metod interfejsu API kolekcji, które mogą się opłacić w inny sposób? Czy taki kod byłby ogólnie bardziej zwięzły?

Powiązane ale różne pytania:

Odpowiedz

3

czuć tak jak Option może lepiej pasować do twojego przypadku użycia.

Moja interpretacja jest taka, że ​​funkcje częściowe dobrze się łączą w stosunku do zakresów wejściowych. Jeśli więc zdefiniowano f przez (SanDiego,Irvine) i g zdefiniowano przez (Paris,London), wówczas można uzyskać funkcję, która jest zdefiniowana przez połączone wejście (SanDiego,Irvine) i (Paris,London) przez wykonanie f orElse g.

Ale w twoim przypadku wydaje się, dzieje się dla danej lokalizacji (l1,l2) krotki a potem popracować ...

Jeśli znajdziesz się pisać dużo {case (L,M) => ... case (P,Q) => ...} to może być znak, że funkcja częściowa są lepiej dopasowane.

przeciwnym wypadku opcje działają dobrze z resztą zbiorów i mogą być używane w ten sposób zamiast swojego (a) Propozycja:

val processedPaths = for { 
    f <- finders 
    p <- f(l1, l2) 
} yield process(p) 

wewnątrz dla zrozumienia p jest podnoszony do w Traversable, więc don” t nawet zadzwonić pod numer filter, isDefined lub get, aby pominąć szukacze bez wyników.

3

Nie jest to aż tak dobrze znane, ale od 2.8 Scala ma metodę collect zdefiniowaną w jej kolekcjach. collect jest podobna do filter, ale przyjmuje częściową funkcję i ma opisaną przez ciebie semantykę.

Powiązane problemy