iT邦幫忙

第 12 屆 iThome 鐵人賽

DAY 27
0
Software Development

Functional Programming in JS系列 第 27

Monad: 圖解篇

恭喜大家跟我一樣到達最後一系列的大魔王魔幻領域 Monad! 我第一次聽到 Monad 腦中只浮現這個 (OS. 好想去迪士尼當工程師可惜北加沒有迪士尼 @@)
https://ithelp.ithome.com.tw/upload/images/20200927/201064266a0W3CNQIN.png

不知道是不是 javaScript 語言特性的關係,我找了好多資料對 Monad 的解釋都不盡相同 XD,先來看看完等於沒看的維基百科解釋

Monad is an abstraction that allows structuring programs generically. Monads achieve this by providing their own data type (a particular type for each type of monad), which represents a specific form of computation, along with one procedure to wrap values of any basic type within the monad (yielding a monadic value) and another to compose functions that output monadic values (called monadic functions). -wiki

下面是一些比較口語化的定義

A way to wrap a value into a context, and a way to unwrap the value from the context

In functional programming, a monad is a structure that represents computations defined as sequences of steps. A type with a monad structure defines what it means to chain operations, or nest functions of that type together

Monad is a type that can flat the functor

整理一下成中文就是(若有錯誤麻煩告訴我)

Monad 常被比喻為洋蔥,其實也是一種設計模式,表示一個運算的過程,通過個別函式拆解後運算再連接這樣的步驟

為何比喻成洋蔥,原因是常在處理包很多層的狀況讓人忍不住想哭,但經過一些方法達到函式拆解後運算再連接,就是 Monad 所做的 (那我覺得應該要叫 "再也不用被洋蔥氣哭神器" 啊)

https://ithelp.ithome.com.tw/upload/images/20200927/20106426m3y5H0zeyW.jpg

實際上 Monad 跟前幾篇講到的 Functor 習習相關,不過這篇盡量不提程式碼,先用圖讓大家了解 Monad 這個運算過程吧,開始之前還是要先從看到膩的 Function 開始說

Function

Function 很像水管,放入一個值,輸出一個值

https://ithelp.ithome.com.tw/upload/images/20200927/2010642686Esb319HW.jpg

const func = intput => intput - 1;
func(3); // 2

也可以很多 Function 接起來一起使用
https://ithelp.ithome.com.tw/upload/images/20200927/20106426044X4dwvZz.jpg

const func1 = intput => intput - 1;
const func2 = intput => intput + 3;
func2(func1(3)); // 5

https://ithelp.ithome.com.tw/upload/images/20200927/20106426XiYMLUs3Q7.jpg

const transformToBox = intput => Effect(intput);
transformToBox(3); // Effect(3)

(↑這個例子毫無意義,不過只是為了示範好懂用啦)

現在我們要定義一種函式,就是輸入輸出都是 Data Type

https://ithelp.ithome.com.tw/upload/images/20200927/20106426VZPW6QJSGB.jpg

實際上是這樣運作的

https://ithelp.ithome.com.tw/upload/images/20200927/20106426HokUL75UK3.jpg

這些運算連起來,就叫做 Monad, Monad 是一種設計模式,表示一個運算的過程,通過個別函式拆解後運算再連接這樣的步驟,只要提供下一個需要運算的函式,運算就會自動進行下去


參考文章

如有錯誤或需要改進的地方,拜託跟我說。
我會以最快速度修改,感謝您

歡迎追蹤我的部落格,除了技術文也會分享一些在矽谷工作的甘苦。


上一篇
[練習] Functor Exercise
下一篇
Either Monad: 更優雅的除錯
系列文
Functional Programming in JS30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

2 則留言

0
taiansu
iT邦新手 4 級 ‧ 2020-09-27 03:28:27

加油!有些部份寫的不錯~ 再撐一下就到終點了!

不過 Monad, 還有之前的 Applicative, Functor 並不是一種「設計模式」,而是一種 typeclass,很簡單的來說是一種「性質」。就像數字可以互相比較大小排序,字串也可以比較大小排序,那麼這兩個 type 都是/有 Ord 這個 typeclass 的實體(instance)。

而陣列/串列有 Monoid, Functor, Applicative, Monad 的實體,所以你可以利用這些性質去組合出操作它的有趣方式。但它不是唯一一種。Tuple, IO, Maybe, Either 都有 Monad 的實體 (所以也會是 Applicative, Functor, Monoid 的實體。)不過這些只在 JS 裡就用不太到了。

如果你學過 JAVA 或是 C# 的話,可以把 typeclass 想像成是類似但是比 interface 好一些的東西。沒有的話就… 就算了。

是說,等你忙完,有空要來看小說噢 XD 基本上裡面有很多「怎麼理解 functional 的過程」的我的詮譯法 (抱歉但其實我沒有要廣告的意思,只是覺得你可以看看 XD)

hannahpun iT邦新手 4 級 ‧ 2020-09-27 13:07:42 檢舉

鐵人賽結束就可以好好看你的小說了 !

2
良葛格
iT邦新手 2 級 ‧ 2020-10-07 10:35:21

關於 Monad,也要知道的是,JavaScript 中沒有對應的實體,只能模擬。

應該說,從 XX 語言認識 FP,最常犯的錯誤就是,試圖找出對應的實體,畢竟使用語言來陳述概念時,往往無法一對一地對應。

真正應該取的是,OO 語言中是因為什麼樣的需求,曾經產生過什麼樣的經驗,然後經過什麼樣的思考重構,才產生這樣的結果,換到 XX 語言時,是否有類似的需求,依該語言的特性,驅使出類似的產物。

需求 -> 經驗 -> 思考 -> 結果…這感覺像是某種經驗上 Pattern?其實我比較愛用 Pattern 來比喻,因為 Pattern 不單是結果,還必須包含「需求、經驗、思考」。

與其找出對等物,不如探討 FP 中是什麼樣的「需求 -> 經驗 -> 思考 -> 結果」的過程,才產生出 Functor、Applicative、Monad …

然後把這樣的「需求 -> 經驗 -> 思考 -> 結果」的過程,用在 JavaScript(或其他語言)時,會產生什麼樣的變化,產生出什麼樣的結果…

Functor、Applicative、Monad …等在 Haskell 並不單純是 Pattern,無法找出 JavaScript 中的對等物,不過「需求 -> 經驗 -> 思考 -> 結果」的這個過程,卻可以轉換。

然而不少文件在討論 FP 時,都只講「結果」…忽略了「需求 -> 經驗 -> 思考」的過程,然後多半就霧裡看花了…也提不出什麼實用性…

如果你稍微瞭解 Java 的話,我過去曾經用 Java 探討過 Monad,然而是從一個需求開始,逐步觀察重複、重構…一直到產生類似 Monad 概念的東西,有興趣可以看一下…在〈Java 8 Patterns〉接近中段的部份開始探討的。

與其找出對等物,我覺得「從一個需求開始,逐步觀察重複、重構…」這過程,才是真正重要的。

我要留言

立即登入留言