Monad詳解

  最近幾年,函數式編程變得越來越流程,其代碼簡潔、副作用小、維護成本低等特點,使得許多其它的語言也開始支持函數式編程,比如JavaC#等。本文主要介紹一下函數式編程中的一個重要概念:Monad
  
  從定義上看,Monad就是兩個接口:一個是return,另一個是一個bind;只要實現這兩個操作的類型,都是monad。但是在理解Monad之前,先要搞清楚兩個概念:FunctorsApplicatives:
  

1. Functors

  • 定義:把一個函數作用在數值類型(對值類型的封裝,包含相關屬性和方法)上,用 fmap 或者 <$> 表示這種運算。

  • 常規運算:把一個函數作用在一個普通數值上

圖1

  • Functors運算: 如果把普通數值用上下文包括,生成一個數值類型,那麼函數將無法處理該數值類型

圖2

函數無法處理數值類型,於是就出現了Functors,它可以處理數值類型,例如:

> fmap (+3) (Just 2)
Just 5

> (+3) <$> (Just 2)
Just 5

圖3

具體操作步驟如下圖解:

圖4

如果數值類型爲Nothing,那麼Functors作用後的結果也是Nothing:

圖5

2. Applicatives

  • 定義: 把一個封裝後的函數作用於數值類型(對值類型的封裝,包含相關屬性和方法),用liftA<*>定義這種運算。

  • 運算法則:可以把Applicatives看成是Functors中的函數也被封裝了一層,然後再應用於數值類型

> Just (+3) <*> Just 2
Just 5

> liftA (Just (+3)) (Just 2)
Just 15

圖6

如果數值類型爲Nothing,那麼Functors作用後的結果也是Nothing:

3. Monad

  • 定義: 把一個返回數值類型的函數作用於數值類型,用liftM>>=來定義這種運算。

  • 運算法則:可以把Monad看成是Applicatives中的函數返回值也是數值類型

圖7

定義half是判斷是否是偶數的函數, 作用於數值類型20,過程如下:

> Just 20 >>= half >>= half >>= half
Nothing

圖8

如果數值類型爲Nothing,那麼Functors作用後的結果也是Nothing:

圖9

由於Nothing作用於FunctorsApplicativesMonad時,都返回Nothing,所以它們都是Maybe類型。Maybe類型的定義如下:
data Maybe a = Nothing | Just a

圖9


參考資料

http://adit.io/posts/2013-04-17-functors,_applicatives,_and_monads_in_pictures.html

http://www.ruanyifeng.com/blog/2015/07/monad.html?utm_source=tuicool

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章