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 => IntKleisli[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 的别名。

10-04 18:37