6

我是一个相对的 Scala 初学者,想要一些关于如何继续实现的建议,看起来它可以通过函数返回 Option 或 PartialFunction 来完成。我已经阅读了我能找到的所有相关帖子(见问题底部),但这些似乎涉及使用 PartialFunction 或将一个转换为另一个的技术细节;我正在寻找“如果情况是 X、Y、Z,则使用 A,否则使用 B,但也考虑 C”类型的答案。

我的示例用例是使用路径查找器库在位置之间进行路径搜索。假设位置是类型L,路径是类型P,并且所需的路径搜索结果是Iterable[P]. 补丁搜索结果应该通过询问所有路径查找器(在 Google 地图中,这些可能是自行车、汽车、步行、地铁等)的路径建议来组装,这些建议可能会或可能不会针对特定的开始/结束位置对。

似乎有两种方法可以解决这个问题:

(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 likefinders.filter(_.isDefined((l1,l2))).map(_.apply((l1,l2)))`

似乎使用返回函数Option[P]可以避免对结果进行双重评估,因此对于昂贵的计算,这可能是可取的,除非缓存结果。似乎使用Option一个可以具有任意输入签名,而PartialFunction需要一个参数。但我特别想听到有实践经验的人关于不太直接、更“大局”的考虑,例如与 Scala 库的交互。使用PartialFunction集合 API 的某些方法是否有显着的好处,而这些方法可能会以其他方式得到回报?这样的代码通常会更简洁吗?

相关但不同的问题:

4

2 回答 2

3

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

我的解释是偏函数可以很好地组合在输入范围内。因此,如果fis defined over(SanDiego,Irvine)并且gis defined over(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)

在 for 理解p中被提升为Traversable,因此您甚至不必调用filterisDefinedget跳过没有结果的查找器。

于 2011-12-01T05:50:12.760 回答
3

这并不是众所周知的,但自 2.8 起,Scalacollect在其集合上定义了一个方法。 collect类似于filter,但采用部分函数并具有您描述的语义。

于 2011-12-01T12:42:17.760 回答