Скала:выбор опции возврата функции в сравнении с PartialFunction

StackOverflow https://stackoverflow.com/questions/8336818

  •  26-10-2019
  •  | 
  •  

Вопрос

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

Мой пример использования - поиск путей между местоположениями с использованием библиотеки средств поиска путей.Допустим, локации относятся к типу L, путь был типа P и желаемым результатом поиска по пути будет Iterable[P].Результат поиска исправлений должен быть собран путем запроса у всех поисковиков пути (в чем-то вроде Google Maps это может быть Велосипед, автомобиль, Прогулка пешком, метро и т.д.) Их предложений по маршруту, которые могут быть определены, а могут и не быть определены для конкретной пары начальное / конечное местоположение.

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

(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искатели.фильтр( _.IsDefined( (l1,l2) ) ).карта( _.применить( (l1,l2)) )`

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

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

Это было полезно?

Решение

Это похоже на Option возможно, это лучше подходит для вашего варианта использования.

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

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

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

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

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

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

Другие советы

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top