Scala:选择返回Option的函数与PartialFunction

6
我是Scala的初学者,并希望在实现一个可以使用返回Option函数或PartialFunction函数完成的操作时得到一些建议。我已经阅读了所有相关的帖子(请参见问题底部),但这些似乎涉及使用PartialFunction或将其转换为另一个函数的技术细节。我正在寻找的是“如果情况是X,Y,Z,则使用A,否则使用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],然后通过类似finders.filter(_.isDefined((l1,l2))).map(_.apply((l1,l2)))的方式获取结果。
使用返回Option [P]的函数似乎避免了结果的双重计算,因此对于昂贵的计算来说,这可能是首选,除非缓存结果。看起来使用Option可以拥有任意数量的输入签名,而PartialFunction则需要一个参数。但我特别想听听有实际经验的人的意见,更多地考虑如何与Scala库进行交互的“更大的图景”问题。使用PartialFunction是否具有使集合API的某些方法可用的重大优势,这可能会在其他方面产生回报?这样的代码一般是否更简洁?
相关但不同的问题:
2个回答

4

并不是所有人都知道,但自从 2.8 版本以来,Scala 的集合中定义了一个 collect 方法。与 filter 相似,但它接受一个偏函数,并具有您所描述的语义。


3

感觉 Option 可能更适合您的用例。

我的理解是,部分函数很适合在输入范围上进行组合。因此,如果 f 定义在 (SanDiego,Irvine) 上,而 g 定义在 (Paris,London) 上,则可以通过执行 f orElse g 来获得一个定义在组合输入 (SanDiego,Irvine)(Paris,London) 上的函数。

但在您的情况下,似乎是对于给定的 (l1,l2) 位置元组发生了一些事情,然后进行一些工作...

如果您发现自己写了很多 {case (L,M) => ... case (P,Q) => ...},那么可能意味着部分函数更适合。

否则,选项与其余集合配合良好,并且可以像这样使用,而不是您提出的(a)建议:

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

在for推导式中,p被提升为一个Traversable对象,因此您甚至不需要调用filterisDefinedget来跳过没有结果的查找器。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接