Kleisli、ReaderT和Reader在Scalaz中为什么相同,这只是巧合吗?

19

在 Scalaz 中:

  • Kleisli[F, A, B]A => F[B] 的封装器。
  • ReaderT[F, A, B] -- 读取器单子转换器 -- 只是 Kleisli[F, A, B] 的别名。
  • Reader[A, B] 单子是使用恒等单子 Id 特化的 ReaderT,即:
    type Reader[A, B] = ReaderT[Id, A, B]

这是否只是巧合呢?还是说在 Scalaz 中 KleisliReaderTReader 是同构的?


2
Reader和ReaderT/Kleisli并不同构(正如您所说,前者是后者的特化)。 - ZhekaKozlov
@ZhekaKozlov 谢谢。我错了(不过不会更新问题)。 - Michael
1个回答

26
你可以将其想象为通过两种不同的方式到达相同的位置。一边是从读者单子开始,它只是一个函数的包装器。然后你意识到你想要将这个读者功能集成到具有其他“效果” 的更大的单子中,因此你创建了一个 ReaderT 单子变换器。在那一点上,将你的原始 Reader[E,?] 实现为 ReaderT[Id,E,?] 是很有道理的。
从另一方面来看,你需要一个类型来表示 Kleisli 箭头 (即带有单调返回类型的函数)。结果发现这与 ReaderT 是相同的,因此你只需将其作为别名。
“结果发现”部分没有什么特别神秘的地方。这有点像如果你最初使用 Addable 类型类来表示类似数字的东西,然后决定使其更通用,并最终得到一个只提供关联“类似加法”的操作的类型类。你重造了 Semigroup!你可能仍然想保留 Addable 名称,出于历史、教育或方便等原因。
这就是 Reader 和 ReaderT 的全部内容——你不需要这些别名,但它们可以很方便,并且有助于提高代码的清晰度。

2
你可以在这里找到Travis解释的例子:http://eed3si9n.com/learning-scalaz/Composing+monadic+functions.html - ssanj

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接