以惯用的方式组合选项

 郭伟健逍遥_308 发布于 2023-02-11 07:41

我将在Scala中编写这个,但它更像是一个函数式编程问题.

我有

def foo(x: A): Option[B]

def bar(x:B, y:B): C

执行以下操作的最佳方法是什么:

def compose(x:A, y:A): Option[C]

如果foo(y)的foo(x)为None,则compose(x,y)为None,否则compose(x,y)为bar(foo(x).get,foo(y).get) .我能想到的最好的是:

foo(a).flatMap( aRes => foo(b).map( bRes => bar(a,b)))

Travis Brown.. 5

以下是您当前解决方案的语法糖:

def compose(x: A, y: A): Option[C] = for {
  fx <- foo(x)
  fy <- foo(y)
} yield bar(fx, fy)

有时,这种方法比写出更好的flatMapmap,有时事实并非如此.你可能会发现你很快就会对这种事情产生强烈的偏好.要么被认为是惯用的Scala.

但是,从功能编程的角度来看,你已经表明你对这个问题更感兴趣,但值得注意的是,上述解决方案在某种意义上来说是过度的.他们利用了Optionmonadic 这一事实,但是对于这个操作,你实际上并不需要所有这些功能 - Option具有应用程序仿函数实例的事实就足够了.非常非正式地总结,flatMap给你在这里不需要的排序,因为计算fy不依赖于计算fx.使用applicative functor Option可以更清楚地捕获两个计算之间没有依赖关系的事实.

斯卡拉标准库不提供任何类型的应用性函子的表示,但Scalaz确实,与Scalaz你可以写你的方法是这样的(见我的回答的"附录" 这里的语法的一些讨论):

import scalaz._, Scalaz._

def compose(x: A, y: A): Option[C] = (foo(x) |@| foo(y))(bar)

这将产生与上面的实现相同的结果,但使用更合适的抽象.

撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有