假设我有一些 Int => Option[Int]
类型的函数:
def foo(n: Int): Int => Option[Int] = {x => if (x == n) none else x.some}
val f0 = foo(0)
val f1 = foo(1)
我可以用 >=>
组合它们,如下所示:
val composed: Int => Option[Int] = Kleisli(f0) >=> Kleisli(f1)
假设现在我需要从列表中组合所有函数:
val fs: List[Int => Option[Int]] = List(0, 1, 2).map(n => foo(n))
我可以使用map
和reduce
来做到这一点:
val composed: Int => Option[Int] = fs.map(f => Kleisli(f)).reduce(_ >=> _)
它(上面的组合
)可以简化吗?
最佳答案
如果您想要组合幺半群(而不是“运行每个并对结果求和”幺半群),则必须使用Endomorphic
包装器:
import scalaz._, Scalaz._
val composed = fs.foldMap(Endomorphic.endoKleisli[Option, Int])
然后:
scala> composed.run(10)
res11: Option[Int] = Some(10)
kleisli 箭头的幺半群只需要输出类型的幺半群实例,而组合幺半群要求输入和输出类型相同,因此后者只能通过包装器使用是有道理的。
关于scala - 组合返回选项的函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31379707/