圖解Monad

jopen 9年前發布 | 8K 次閱讀 Monad

函數式編程有一個重要概念,叫做 Monad

圖解Monad

網上有很多解釋(這里這里),但都很抽象,不容易看懂。我嘗試了好多次,還是不明白 Monad 到底是什么。

圖解Monad

昨天,我讀到了 Aditya Bhargava 的文章,他畫了很多圖。我想了半天,終于恍然大悟。下面,我就用這些圖來解釋 Monad。

1.

圖解Monad

軟件最基本的數據,就是各種值(value)。

2.

圖解Monad

處理值的一系列操作,可以封裝成函數。輸入一個值,會得到另一個值。上圖的"(+3)"就是一個函數,對輸入的值加上3,再輸出。

3.

圖解Monad

函數很像漏斗,上面進入一個值,下面出來一個值。

4.

圖解Monad

函數可以連接起來使用,一個函數接著另一個函數。

5.

圖解Monad

函數還可以依次處理數據集合的每個成員。

6.

圖解Monad

說完了函數,再來看第二個概念:數據類型(type)。

數據類型就是對值的一種封裝,不僅包括值本身,還包括相關的屬性和方法。上圖就是 2 的封裝,從此 2 就不是一個單純的值,而是一種數據類型的實例,只能在數據類型的場景(context)中使用。

7.

圖解Monad

2 變成數據類型以后,原來的函數就不能用了。因為"(+3)"這個函數是處理值的(簡稱"值函數"),而不是處理數據類型的。

8.

圖解Monad

我們需要重新定義一種運算。它接受"值函數"和數據類型的實例作為輸入參數,使用"值函數"處理后,再輸出數據類型的另一個實例。上圖的 fmap 就代表了這種運算。

9.

圖解Monad

fmap 的內部,實際上是這樣:打開封裝的數據類型,取出值,用值函數處理以后,再封裝回數據類型。

10.

圖解Monad

一個有趣的問題來了。如果我們把函數也封裝成數據類型,會怎樣?

上圖就是把函數"(+3)"封裝成一種數據類型。

11.

圖解Monad

這時,就需要再定義一種新的運算。它不是值與值的運算,也不是值與數據類型的運算,而是數據類型與數據類型的運算。

上圖中,兩個數據類型進行運算。首先,取出它們各自的值,一個是函數,一個是數值;然后,使用函數處理數值;最后,將函數的返回結果再封裝進數據類型。

12.

圖解Monad

函數可以返回值,當然也可以返回數據類型。

13.

圖解Monad

我們需要的是這樣一種函數:它的輸入和輸出都是數據類型。

14.

圖解Monad

這樣做的好處是什么?

因為數據類型是帶有運算方法的,如果每一步返回的都是數據類型的實例,我們就可以把它們連接起來。

15.

圖解Monad

來看一個實例,系統的I/O提供了用戶的輸入。

16.

圖解Monad

getLine 函數可以將用戶的輸入處理成一個字符串類型(STR)的實例。

17.

圖解Monad

readfile 函數接受 STR 實例當作文件名,返回一個文件類型的實例。

18.

圖解Monad

putStrLn 函數將文件內容輸出。

19.

圖解Monad

所有這些運算連起來,就叫做 Monad。

簡單說,Monad 就是一種設計模式,表示將一個運算過程,通過函數拆解成互相連接的多個步驟。你只要提供下一步運算所需的函數,整個運算就會自動進行下去。

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!