簡體   English   中英

在Haskell中列出monad的實例 - 為什么在bind-operation中使用concat?

[英]List instance of monad in Haskell - why use concat in bind-operation?

我在這里找到了一些問題: 重新定義monad list實例 我現在正試圖把頭包裹在monad周圍。 但是我需要一些幫助,我不會將列表的實例定義作為monad。

這是我給monad的列表實例的定義:

    instance Monad [] where
    xs >>= f = concat $ map f xs
    return x = [x]
    fail _ = []

我不明白,為什么我需要在bind-function中使用concat。 這是我對(>>=)定義:

    (>>=) :: Monad m => m a -> (a -> m b) -> m b

所以我有一些monadic值ma和一個函數,取值a並產生作為參數給出的monadic值mb 我“喂” ama到函數(a -> mb) ,從而得到一個monadic值mb作為結果。 用我自己的話說:bind-operator (>>=)允許鏈接monadic函數(返回monadic值),其中較早函數的輸出值是下一個函數的輸入。 對?

回到列表實例。 map f xsxs每個值上使用函數f 因此, map (*2) [1,2,3]導致[2,4,6] 這就是我想要的全部與否? 我該如何在這里使用concat concat的定義如下:

    concat :: [[a]] -> [a]

為什么我得到(>>=) -function中的列表列表? 是因為list是monad而且我從該列表中獲取每個值以將其提供給f並且map只獲取singleton-inputs? 但是,如何迭代整個列表呢? “挑選每個價值”在哪里發生? 如果map將整個列表xs作為輸入(這就是我理解它的原因)為什么我應該得到一個列表列表?

如果

x :: [a]
f :: a -> [b]

然后

map f :: [a] -> [[b]]
map f x :: [[b]]

所以,我們需要將后者扁平化為[b] 這是由concat完成的。

請注意f是如何生成列表的,因此map將其轉換為列表列表。 這是至關重要的:如果f沒有產生列表但是f :: a->b ,那么我們不需要concat - 我們甚至不需要monad,因為提供fmap=map :: (a->b) -> [a] -> [b]函數) fmap=map :: (a->b) -> [a] -> [b]就足夠了。

monad相對於functor的額外好處主要在於讓f產生monadic類型的值。

暫無
暫無

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

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