[英]Compose nested Monads in Haskell
有沒有辦法為嵌套monad實現bind? 我想要的是以下簽名:
(>>>=) :: (Monad m, Monad n) => m (n a) -> (a -> m (n b)) -> m (n b)
它看起來應該是一項微不足道的任務,但我不知何故無法繞過它。 在我的程序中,我將這種模式用於monad的幾種不同組合,對於每種組合,我都可以實現它。 但對於一般情況,我只是不明白。
編輯:似乎在一般情況下不可能。 但在某些特殊情況下肯定是可能的。 例如,如果內在的Monad是一個Maybe。 因為我想要使用的所有Monads都可以使用,所以有額外的限制似乎對我來說很好。 所以我稍微改變了一下這個問題:
我需要對n進行哪些額外限制,以便可以進行以下操作?
(>>>=) :: (Monad m, Monad n, ?? n) => m (n a) -> (a -> m (n b)) -> m (n b)
擴展評論:如鏈接 問題所示,有必要使用某個函數n (ma) -> m (na)
甚至有機會使合成成為monad。
如果你的內部monad是一個Traversable
,那么sequence
提供了這樣一個函數,以下將具有正確的類型 :
(>>>=) :: (Monad m, Monad n, Traversable n) => m (n a) -> (a -> m (n b)) -> m (n b)
m >>>= k = do
a <- m
b <- sequence (map k a)
return (join b)
幾個着名的變換器實際上是簡單的newtype包裝器,而不是相當於它的東西(雖然主要用模式匹配來定義事物而不是字面上使用內部monad的Monad
和Traversable
實例):
MaybeT
基於Maybe
ExceptT
基於Either
WriterT
基於(,)
(,)
通常不具備其Monad
實例定義, 並 WriterT
使用錯誤的元組為了使用它,如果它有-但在精神上它可能有)。 ListT
基於[]
。 噢, 哎呦 ...... 最后一個實際上因為不是單子而臭名昭着,除非被提升的單子是“可交換的” - 否則,單子法應該相等的表達可以給出不同的效果順序。 我的預感是,這主要來自列表能夠包含多個值,而不像其他可靠的工作示例。
因此,雖然上面的定義將被正確輸入 ,但它仍然可以打破monad定律。
另外,作為一個事后的想法,另一個變換器是這樣一個嵌套的monad,但是以完全不同的方式: ReaderT
,基於使用(->)
作為外部 monad。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.