簡體   English   中英

在Haskell中編寫嵌套的Monads

[英]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的MonadTraversable實例):

  • MaybeT基於Maybe
  • ExceptT基於Either
  • WriterT基於(,) (,)通常不具備其Monad實例定義, WriterT使用錯誤的元組為了使用它,如果它有-但在精神上它可能有)。
  • ListT基於[] 噢, 哎呦 ......

最后一個實際上因為不是單子而臭名昭着,除非被提升的單子是“可交換的” - 否則,單子法應該相等的表達可以給出不同的效果順序。 我的預感是,這主要來自列表能夠包含多個值,而不像其他可靠的工作示例。

因此,雖然上面的定義將被正確輸入 ,但它仍然可以打破monad定律。

另外,作為一個事后的想法,另一個變換器是這樣一個嵌套的monad,但是以完全不同的方式: ReaderT ,基於使用(->)作為外部 monad。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM