2016-03-03 33 views
2

我發現Option Monad要直觀明白,而List不是。單子綁定操作不直觀遵循

Some(1) >>= { x=>Some(x+1)} 
Ma -> a -> Mb -> Mb 

如果我提取一些值(1)我知道這是1

但列表中的情況下

List(3,4,5) flatMap { x=> List(x,-x) } 

如果我提取列表值,我能得到什麼?如何使理解過程直觀

+0

列表背後的一元直覺是列表值函數一次返回多個結果。那麼,當你結合(有點撰寫,但在單一世界中)兩個列表值函數時會發生什麼?第一個計算許多結果,然後將它們全部提供給第二個函數,該函數計算每個輸入的許多結果。希望澄清一些事情。 –

回答

3

直觀後面的OptionMaybe實際上非常類似於List monad。主要區別在於List是非確定性的 - 我們不知道我們可以得到多少個值,當與Option時,它總是一個成功,失敗時爲零。空列表被視爲失敗。

我覺得這piece描述它相當不錯:

對於清單,單子結合包括在列表中的每個值拼接一套 計算。當與列表中使用,>> =的 簽名變爲:

(>> =):: [A] - >(A - >並[b]) - >並[b]

即,給定a列表和將a映射到b的列表 的函數列表,綁定將該函數應用於輸入 中的每個a,並將所有生成的b連接成一個列表。

和列表實現的example

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

對不起,我把哈斯克爾到斯卡拉的答案,但是這是我用來了解這個東西的資源。

斯卡拉的flatMap不完全是哈斯克爾的綁定>>=,但非常接近它。那麼,所有這一切意味着?:

想象一下,你有客戶List[Client]列表的實際情況,可以將它們綁定到訂單List[Order]將與flatMap>>=自動展平爲你的一個列表。如果您將使用map,您將得到一個List[List[Order]]。在實踐中,您將提供使用>>=的功能,同樣地,您如何提供fold的功能 - 您決定如何生成/彙總數據等。對你而言,綁定的作用是提供一個用於組合兩個monadic值的通用模式,並且對於每種類型的monad實現將是唯一的。

你可能會喜歡看它的抽象爲多個級別(從更一般的少):

  1. 單子已經綁定的操作,將在兩個單子值組合成一個:(>>=) :: m a -> (a -> m b) -> m b

  2. List作爲monad實例使用類似下面的方法實現綁定:xs >>= f = concat (map f xs) - 將函數映射到所有元素並將結果連接到單個列表中。

  3. 根據您的需要(客戶端 - >訂單示例),您可以爲綁定功能提供函數f的實現。

一旦你知道綁定的行爲爲您的單子實例(ListOption)你能想到的只是用它和「忘記」關於實際執行的條款。

+0

這裏「失敗」是什麼意思? 「空列表被認爲是失敗。」 – drstevens

+0

感謝您的詳細回覆。實施使我的行動清晰。但沒有,我仍然不能說這是直觀的。還有'functor' monad等等......這是否意味着沒有實現它就不直觀。 – zinking

+0

@drstevens通常我們有一個成功的價值,當我們沒有價值時失敗。空選項或空列表失敗。在實踐中,這意味着你在預期時未能獲得某種價值。 –