我可以做很多事來擴展這個問題。但這裏是一個用例:假設您有兩個單子變壓器,t
和s
,轉化在相同的單子m
:如果兩個monad變換器的類型不同,是否有原則性的構成方式,但是它們的基礎monad是相同類型的?
master :: (MonadTrans t, Monad m) => t m a b
slave :: (MonadTrans t, Monad m) => s m a b
我要撰寫master
和slave
使得它們能夠相互通信時,基元被提升到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
以前不可能明智地組成,但是在包裝一些底層monad m
之後,它們現在可以被組合並作爲單個功能運行。至於組合函數的類型,我真的不確定是否讚賞某些方向。現在,如果這種抽象已經存在,我只是不知道它,那麼這將是最好的。
是's'和't'是否任意或者它們是某種特定的 - 我們是否試圖創造這樣的's'和't'?同樣的問題也適用於'm' - 它和它的'send'和'receive'怎麼樣? –
是's'和't'是任意的。 'm'是我們試圖在這裏創建的具體類型。 'send'和'receive'分別是'(a,Bool) - > m a b'和'm a b'類型的原始函數。但是他們對我提供的人爲使用案例是偶然的,他們實施的細節並不重要。 – chibro2