在斯卡拉兹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]
。
是只是巧合还是Scalaz中Kleisli
,ReaderT
和Reader
同构的更深层原因?
最佳答案
您可以认为它是通过两条不同的路线到达同一地点的。一方面,您从阅读器monad开始,它只是一种函数包装。然后,您意识到要将此阅读器功能与其他“效果”集成到更大的monad中,因此您创建了ReaderT
monad转换器。此时,将您原始的Reader[E, ?]
实现为ReaderT[Id, E, ?]
是有意义的。
另一方面,您需要一种类型来表示Kleisli箭头(即具有一元返回类型的函数)。事实证明,这与ReaderT
是同一回事,因此只需将其命名为别名即可。
“结果”部分没有什么特别的神秘之处。这有点像是从一个Addable
类型类开始处理类似数字的事情,然后决定使其变得更通用,最后最终得到一个类型类,该类型类仅提供关联的“类似加法”操作。您已经重新发明了Semigroup
!但是,出于历史或教学上的原因,或者只是为了方便起见,您可能仍要保留Addable
名称。
这就是Reader
和ReaderT
所发生的全部—您不需要这些别名,但是它们可以很方便,并且可以帮助提高代码的清晰度。
关于scala - Scalaz中的Kleisli,ReaderT和Reader相同只是一个巧合吗,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/29226560/