在Scalaz
Kleisli[F, A, B]
是A => F[B]
的包装器。 ReaderT[F, A, B]
- 阅读器monad变换器 - 只是Kleisli[F, A, B]
的别名。 Reader[A, B]
monad是ReaderT
的标识monad Id
的专精:type Reader[A, B] = ReaderT[Id, A, B]
。 这只是一个巧合,还是有一些更深层的原因导致Kleisli
,ReaderT
和Reader
在Scalaz中同构?
答案 0 :(得分:22)
您可以将其视为通过两条不同的路线到达同一个地方。一方面,你从阅读器monad开始,它只是一种函数包装器。然后你意识到你想要将这个阅读器功能集成到一个更大的monad和其他"效果",所以你创建了一个ReaderT
monad变换器。此时,将原始Reader[E, ?]
实现为ReaderT[Id, E, ?]
。
另一方面,您需要一种类型来表示Kleisli箭头(即具有monadic返回类型的函数)。事实证明这与ReaderT
是一样的,所以你只需要把它作为别名。
对于&#34而言,没有什么特别神秘的事情。事实证明"部分。如果你开始使用类似数字的Addable
类型类,然后决定使它更通用,并最终得到一个只提供关联的类型类,那就有点像#34 ;另外状"操作。你重新发明了Semigroup
!不过,出于历史或教学原因,或者仅仅是为了方便起见,您可能仍希望保留Addable
名称。
Reader
和ReaderT
所发生的一切 - 您不需要 这些别名,但它们可以很方便,可能有助于提高代码的清晰度。