我很难扩展这个问题。但是这里有一个使用案例:假设你有两个单子变换器 t
和 s
,它们在相同的单子 m
上进行变换:
master :: (MonadTrans t, Monad m) => t m a b
slave :: (MonadTrans t, Monad m) => s m a b
我希望能够组合主节点
和从节点
,使它们可以在将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
更新:
send
和 receive
是类型为m
的原语。如果这个例子看起来很牵强,或者太像协程,请忽略所有相似之处,因为问题的实质与此无关。但主要观点是,在两个单子
t
和s
之前无法合理地组合彼此,但在它们都包装了一些底层单子m
之后,它们现在可以组合并作为一个单一函数运行。至于组合函数的类型,我真的不确定,所以需要一些指导。如果这种抽象已经存在,而我只是不知道它,那就最好了。
s
和t
是任意的还是有特定的含义 - 我们是否试图创建这样的s
和t
?同样的问题也适用于m
- 它以及它的send
和receive
是否有特定的含义? - Petrs
和t
是任意的。m
是我们在这里尝试创建的特定类型。send
和receive
只是类型为(a,Bool) -> m a b
和m a b
的原始函数。但它们与我提供的人为用例无关,它们的实现细节并不重要。 - xiaolingxiao