scala - 组合返回选项的函数

标签 scala monads scalaz kleisli

假设我有一些 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))

我可以使用mapreduce来做到这一点:

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/

相关文章:

performance - Repa 3 性能和正确使用 'now'

Scala,Either[_,Seq[Either[_,T]] 到 Either[_,Seq[T]]

validation - Scalaz 验证,验证内部值

scala - Tuple2._2 用作 map.apply 中的键

scala - 将Scala Iterable [tuple]转换为RDD

scala - 如何为无参数函数定义scala类型?

scala - 使用 scalaz 实现 Either、Left、Right 的简单示例

scala - 如何以编程方式编译和运行 Scala 代码

scala - 警告 :(55, 56) MoldPiece[PressureData(Int, Prettyprint.YesNo)] 上尚不存在 `withFilter' 方法,请改用 `filter' 方法

scala - 是否可以改进 Scala 中部分应用类型的类型推断?