【问题标题】:Scala: selecting function returning Option versus PartialFunctionScala:选择返回 Option 与 PartialFunction 的函数
【发布时间】:2012-01-10 07:56:20
【问题描述】:

我是一个相对的 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 的某些方法方面具有显着优势?这样的代码一般会更简洁吗?

相关但不同的问题:

【问题讨论】:

    标签: scala option partialfunction


    【解决方案1】:

    感觉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 comprehension 中,p 被提升为 Traversable,因此您甚至不必调用 filterisDefinedget 即可跳过没有结果的查找器。

    【讨论】:

      【解决方案2】:

      这并不是众所周知的,但是从 2.8 开始,Scala 在它的集合上定义了一个collect 方法。 collectfilter 类似,但采用偏函数并具有您描述的语义。

      【讨论】:

        猜你喜欢
        • 2011-07-08
        • 1970-01-01
        • 2014-04-13
        • 1970-01-01
        • 1970-01-01
        • 2016-08-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多