在scalaz中,Kleisli[M[_], A, B]
是A => M[B]
的包装,它允许组合此类功能。例如,如果 M[_]
是 monad,我可以用 Kleisli[M, A, B]
组合 Kleisli[M, B, C]
和 >=>
以获得 Kleisli[M, A, C]
。
简而言之,Kleisli
根据 andThens
提供花哨的 M
。这是正确的吗 ?使用 Kleisli
是否还有其他好处?
最佳答案
这里有两个好处作为例子——我相信你可以想出其他的。
首先,抽象不同的箭头会很有用,例如 Kleisli[M, ?, ?]
和 ? => ?
。例如,我可以编写一个泛型函数,该函数将应用一定次数的内同态。
def applyX10[Arr[_, _]: Category, A](f: Arr[A, A]) =
List.fill(10)(Endomorphic(f)).suml
现在我可以在例如使用它
Int => Int
或 Kleisli[Option, Int, Int]
:val f = (_: Int) + 1
val k = Kleisli.kleisli[Option, Int, Int] {
case i if i % 2 == 0 => Some(i * 3)
case _ => None
}
然后:
scala> applyX10(f).run(1)
res0: Int = 11
scala> applyX10[=?>, Int](k).run(2)
res1: Option[Int] = Some(118098)
(注意
A =?> B
只是 Kleisli[Option, A, B]
的别名。)其次,如果
Kleisli[F, ?, ?]
有,那么 F
有一个 monad 实例的事实也很有用。例如,请参阅 my answer here 以演示如何将 monadic 组合与 ReaderT
一起使用,这只是 Kleisli
的别名。