chi*_*ro2 2 monads haskell monad-transformers
假设我有函数组成两个monad动作:
co :: Monad m => m a -> m a -> m a
您可以将其co视为更高阶函数,描述两个monadic动作如何相互合作以完成任务.
但现在我发现第一个monadic动作可能包含在monad变换器中,而第二个不是:
one :: (MonadTrans t, Monad m) => t m a
two :: Monad m => m a
但是还是想把它们组合在一起,所以我需要一个功能:
co' :: (MonadTrans t, Monad m) => t m a -> m a -> t m a
因此,第一个t m a可以m a通过将所有m原语提升到上下文中来合作t.
这里的诀窍是在co不知道mor 的实现的情况下构建t.我觉得答案是在MFunctor包中的某个地方,事实上昨天也提出了类似的问题.但是想不出什么好的,有什么想法吗?
您可以hoist从mmorph包中使用. hoist允许你修改实现的任何东西的基本monad MFunctor(大多数monad变换器):
hoist :: (MFunctor t) => (forall x . m x -> n x) -> t m r -> t n r
Run Code Online (Sandbox Code Playgroud)
然后你可以用它来解决你的问题:
co' tma ma = hoist (co ma) tma
Run Code Online (Sandbox Code Playgroud)
那你就完成了!
为了理解其工作原理,让我们一步一步地查看类型:
co :: (Monad m) => m a -> m a -> m a
ma :: (Monad m) => m a
co ma :: (Monad m) => m a -> m a
hoist (co ma) :: (Monad m, MFunctor t) => t m a -> t m a
tma :: (Monad m, MFunctor t) => t m a
hoist (co ma) tma :: (Monad m, MFunctor t) => t m a
Run Code Online (Sandbox Code Playgroud)
请注意,hoist它必须满足某些法律,以确保它能够做到您所期望的"正确的事情":
hoist id = id
hoist (f . g) = hoist f . hoist g
Run Code Online (Sandbox Code Playgroud)
这些只是函子定律,保证hoist直观行为.
hoist包装Control.Monad.Morph模块中提供了mmorph您可以在此处找到的模块.主模块的底部有一个教程,教授如何使用该包
| 归档时间: |
|
| 查看次数: |
203 次 |
| 最近记录: |