gpt4 book ai didi

haskell - 如果两个 monad 转换器属于不同类型,但它们的底层 monad 属于同一类型,是否有原则性的方法来组合它们?

转载 作者:行者123 更新时间:2023-12-02 13:33:10 26 4
gpt4 key购买 nike

我无能为力来扩展这个问题。但这里有一个用例:假设您有两个 monad 转换器,ts,它们在同一个 monad m 上进行转换:

master :: (MonadTrans t, Monad m) => t m a b
slave :: (MonadTrans t, Monad m) => s m a b

我想组合masterslave,以便当m原语提升到t时它们可以相互通信s。签名可能是:

bound :: (MonadTrans t, MonadTrans s, Monad m, Monoid a) => t m a b -> s m a b -> (...)
But what is the type of (...) ?

一个用例,用糖化符号表示:

master :: Monoid a => a -> t m a b
master a = do
a <- lift . send $ (a,False) -- * here master is passing function param to slave
... -- * do some logic with a
b <- lift . send $ (mempty,True) -- * master terminates slave, and get back result

slave :: Monoid a => (a -> b) -> s m a b
slave g = do
(a,end) <- lift receive
case end of
True -> get >>= \b -> exit b
_ -> (modify (++[g a])) >> slave g

更新:sendreceivem 类型的原语。

如果这个例子看起来很做作,或者太像协程,我深表歉意,问题的精神实际上与它无关,所以请忽略所有相似之处。但要点是 monad t 和 s 之前无法合理地彼此组合,但在两者都包装了一些底层 monad m 后,它们现在可以作为单个函数组合和运行。至于组合函数的类型,我真的不确定,因此希望得到一些指导。现在,如果这个抽象已经存在并且我只是不知道它,那么那就最好了。

最佳答案

是的。将 mmorph 包中的 hoistlift 结合起来即可实现此目的:

bound
:: (MonadTrans t, MonadTrans s, MFunctor t, Monad m)
=> t m () -> s m () -> t (s m) ()
bound master slave = do
hoist lift master
lift slave

要了解其工作原理,请研究提升机的类型:

hoist :: (MFunctor t) => (forall x . m x -> n x) -> t m r -> t n r

hoist 允许您修改任何实现 MFunctor(其中大部分)的 monad 转换器的基本 monad。

bound 的代码所做的是让两个 monad 转换器就最终目标 monad 达成一致,在本例中为 t (s m)。嵌套 ts 的顺序由您决定,所以我只是假设您希望 t 位于外部。

然后,只需使用 hoistlift 的各种组合来让两个子计算在最终的 monad 堆栈上达成一致。第一个的工作原理如下:

master :: t m r
hoist lift master :: t (s m) r

第二个的工作原理如下:

slave :: s m r
lift slave :: t (s m) r

现在他们都同意了,所以我们可以在同一个 do block 中对它们进行排序,并且它会“正常工作”。

要了解有关 hoist 工作原理的更多信息,我建议您查看 the documentation对于具有 a nice tutorialmmorph 包在底部。

关于haskell - 如果两个 monad 转换器属于不同类型,但它们的底层 monad 属于同一类型,是否有原则性的方法来组合它们?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18364808/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com