Scala: выбор функции, возвращающей Option против PartialFunction - PullRequest
6 голосов
/ 01 декабря 2011

Я относительный новичок в Scala и хотел бы получить несколько советов о том, как продолжить реализацию, которая, кажется, может быть реализована либо с помощью функции, возвращающей Option, либо с PartialFunction. Я прочитал все похожие посты, которые смог найти (см. Нижнюю часть вопроса), но, похоже, они связаны с техническими деталями использования PartialFunction или преобразования одного в другое; Я ищу ответ типа «если обстоятельства X, Y, Z, то используйте A еще B, но также рассмотрите C».

Мой пример использования - это поиск пути между местоположениями с использованием библиотеки поиска путей. Скажем, местоположения имеют тип L, путь имел тип P, и желаемый результат поиска пути будет Iterable[P]. Результат поиска патча должен быть собран путем запроса всех путей поиска (в чем-то вроде карт Google это могут быть Bicycle, Car, Walk, Subway и т. Д.) Для их предложений пути, которые могут быть или не быть определены для конкретного старта / пара конечных местоположений.

Кажется, есть два способа сделать это:

(a) определите искатель пути как f: (L,L) => Option[P], а затем получите результат через что-то вроде finders.map( _.apply(l1,l2) ).filter( _.isDefined ).map( _.get )

(b) определить искатель пути как f: PartialFunction[(L,L),P] and then get the result via something like finders.filter (_.isDefined ((l1, l2))) .map (_.apply ((l1, l2))) `

Похоже, что использование функции, возвращающей Option[P], позволит избежать двойной оценки результатов, поэтому для дорогостоящих вычислений это может быть предпочтительным, если не кэшировать результаты. Также кажется, что при использовании Option можно иметь произвольную входную сигнатуру, тогда как PartialFunction ожидает один аргумент. Но мне особенно интересно услышать от кого-то, имеющего практический опыт, о менее неотложных, более "более широких картинах", таких как взаимодействие с библиотекой Scala. Будет ли использование PartialFunction значительным преимуществом в предоставлении определенных методов API коллекций, которые могут окупиться другими способами? Будет ли такой код более кратким?

Смежные, но разные вопросы:

Ответы [ 2 ]

3 голосов
/ 01 декабря 2011

Это не так уж и хорошо известно, но начиная с 2.8 Scala имеет метод collect, определенный в своих коллекциях. collect похож на filter, но принимает частичную функцию и имеет семантику, которую вы описываете.

3 голосов
/ 01 декабря 2011

Такое ощущение, что Option может лучше соответствовать вашему варианту использования.

Моя интерпретация заключается в том, что частичные функции хорошо работают при комбинировании во входных диапазонах. Таким образом, если f определено для (SanDiego,Irvine), а g определено для (Paris,London), то вы можете получить функцию, которая определена для комбинированного ввода (SanDiego,Irvine) и (Paris,London), выполнив f orElse g.

Но в вашем случае, кажется, что вещи происходят с данным кортежем (l1,l2), и затем вы выполняете некоторую работу ...

Если вы часто пишете {case (L,M) => ... case (P,Q) => ...}, это может быть признаком того, что частичные функции лучше подходят.

В противном случае параметры работают хорошо с остальными коллекциями и могут использоваться следующим образом вместо вашего (а) предложения:

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

В пределах понимания p превращается в Traversable, поэтому вам даже не нужно звонить filter, isDefined или get, чтобы пропустить искатели без результатов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...