我是一个相对的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 like
查找器。过滤器(_。isDefined((l1,l2))地图(_。Apply ((l1,l2)) '
似乎使用返回Option[P]
的函数可以避免结果的双重计算,所以对于昂贵的计算,除非缓存结果,否则这可能是更可取的。似乎使用Option
可以有任意的输入签名,而PartialFunction
只需要一个参数。但我特别感兴趣的是听到有实践经验的人谈论一些不那么直接的、更"宏观"的考虑,比如与Scala库的交互。使用PartialFunction
是否在使集合API的某些方法可用方面具有显著的好处,而这些方法可能以其他方式获得回报?这样的代码通常会更简洁吗?
相关但不同的问题:
- PartialFunction's升力方法逆
- PartialFunction设计效率低吗?
- 如何转换X =>选项[R]到PartialFunction[X,R] 在Scala中是否有更好的方法来提升PartialFunction ?
- 在局部函数的isDefined和Apply中发生的昂贵计算
这并不是所有人都知道的,但是自从2.8 Scala在它的集合上定义了一个collect
方法。collect
类似于filter
,但采用部分函数,并且具有您描述的语义。
感觉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
,因此您甚至不必调用filter
, isDefined
或get
来跳过没有结果的查找器。