例如,拥有...
consumer :: Proxy p => () -> Consumer p a (EitherT String IO) ()
producer :: Proxy p => () -> Producer p a (EitherT ByteString IO) r
...我如何使这项工作?
session :: EitherT ByteString (EitherT String IO) ()
session = runProxy $ producer >-> consumer
备注 : 我读过Mixing Base Monads在
Control.Proxy.Tutorial
.我得到了第一个示例,但无法理解人为的示例。更多的例子,不是那么明显但不是那么做作,可能会阐明如何使用 hoist
和 lift
匹配基本单子(monad)的任何组合。
最佳答案
假设你有一个像 MT1 MT2 MT3 M a
这样的单子(monad)变压器堆栈。在哪里 M
是基础单子(monad)。
使用 lift
,您可以在左侧添加一个新的 monad 转换器。它可以是任何变压器,所以我们用 ?
来表示它。 .lift :: MT1 MT2 MT3 M a -> ? MT1 MT2 MT3 M a
使用 hoist
,您可以操作最左侧元素右侧的 monad 堆栈。怎么操作?例如,通过提供 lift
:hoist lift :: MT1 MT2 MT3 M a -> MT1 ? MT2 MT3 M a
使用 hoist
的组合和 lift
,您可以在 monad 转换器堆栈中的任何位置插入这些“通配符”。hoist (hoist lift) :: MT1 MT2 MT3 M a -> MT1 MT2 ? MT3 M a
hoist (hoist (hoist lift)) :: MT1 MT2 MT3 M a -> MT1 MT2 MT3 ? M a
此技术可用于均衡您示例中的两个 monad 堆栈。
关于haskell - 在基本单子(monad)中将代理与不同的 EitherT 组合起来,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14875000/