在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
还有其他好处吗?
答案 0 :(得分:10)
以下是两个好处 - 我确定你可以拿出其他人。
首先,对不同的箭头进行抽象可能很有用,例如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,了解如何使用ReaderT
使用monadic合成,这只是Kleisli
的别名。