談談我對Monad的理解
一、迷失於Monad的汪洋大海
第一次看見這個概念是兩年前,這個詞有著非常不通俗的翻譯:“單子”。那時候受王垠影響在看Scheme和Haskell,對於Scheme的continuation和Haskell的Monad百思不得其解。直覺告訴我,這倆貨之間有著千絲萬縷的聯絡。當時對於型別可計算的概念也是毫無概念,作為剛從Java Web轉到程式語言研究的我真是菜的不行,如飢似渴的在網上找資料各種讀,越讀越迷惑,後來不得不放下。
二、和Monad的幾個照面
而後自己寫了幾個很菜的編譯器,和效能啊新特性啊什麼的毫不沾邊。
看別人部落格的文章照貓畫虎也寫過Monadic的語法分析器,也用過C#大法的Linq,然而並沒有使我明白Monad是個啥。
Linq中的
from a in A
from b in B
from c in C
select f(a,b,c)
其實可以轉化為這種結構:
A.SelectMany(a=>
B.SelectMany(b=>
C.Select(c=> f(a,b,c)
)
)
);
再後來在深入淺出node.js裡見識了js的巢狀callback,因此看到了promise。
巢狀callback的程式碼:
A.fuck1(function(a){
B.fuck2(function(b){
C.fuck3(function(c){
f(a,b,c);
}
}
});
promise把巢狀callback改寫成這種風格(大概,虛擬碼):
Promise.then(A.fuck1)
.then(B.fuck2)
.then(C.fuck3)
.then(function(a,b,c){
f(a,b,c);
})
.done();
當時讀來毫無感覺,現在細想毛骨悚然。
熟悉Scheme的孩子應該一眼就能發現這裡面有CPS變換。
所謂CPS變換就是把所有g(f(x))都給改寫成f(x, r=>g(r))的過程。然而這有和Monad有什麼關係?Monad到底是個啥?
CPS變換和Monad是一家親。CPS變換是說變換過程,而Monad是具備某種能力的“物件”。所謂具備某種能力其實就是Monad具備這種把巢狀式的金字塔結構打平成鏈式結構的能力。Promise差不多算是和Linq有異曲同工之妙。兩者都是Monad的應用。Monad的定義涉及了一些型別計算,其實是很簡單的東西,只是寫成學術符號立刻讓人看不懂了。
最近讀了一篇文章聯想起之前的Linq和promise,彷彿是有點恍然大悟的感覺。
在Swift裡,“一個實現了 flatMap方法的型別其實就是 monad”。
public func flatMap<U>(f: (Wrapped) -> U?) -> U? {
switch self {
case .Some(let y): return try f(y)
case .None: return .None
}
}
flatMap接受一個函式f做引數,返回一個Optinal U型別。f接受Optional型別包裹的型別,返回Optinal U型別。
下面是Optional的定義:
enum Optional<T> {
case None
case Some(T)
}
這只是一個很小的關於Optianal<T>的簡單例子,其實實現了flatMap的類都可以稱作Monad。
當然Monad可不僅僅是這樣,當年在Haskell裡面反正是看的雲裡霧裡。熟悉型別推導的孩子可以推導一下型別,看看為毛promise可以寫成那樣。哦,我忘了,js是弱型別的!
其實這篇文章我倒沒打算把Monad講明白,因為畢竟我是跌跌撞撞走過了很多彎路才明白了型別計算,continuation才最終走到了Monad面前,不敢說自己有什麼理解,只是通俗的明白了這貨原來真的有用,而且用的還不少,只是學術性太強導致曾經看過的資料總有些說不清道不明,感覺有道鴻溝橫在眼前。
之所以寫這篇是因為我知道這個概念太久,如鯁在喉。
貼上兩篇有啟發的文章:
http://www.cppblog.com/vczh/archive/2013/07/27/202154.html
最後感慨一下,vczh大神的高度果然不是我這等渣渣可以企及的。當年太菜沒看懂幾篇vczh的部落格,淚流滿面。
相關文章
- 談談我對Spring IOC的理解Spring
- 談談我對服務化的理解
- 談談我對服務網格的理解
- 談談我對js中閉包的理解JS
- 談一談我對Spring Resource的理解Spring
- 談談我對學生浮躁心裡的理解
- 談談我對Android安全機制的理解Android
- 談談我對物件導向以及類與物件的理解物件
- 談一談我對‘模板方法’設計模式的理解(Template)設計模式
- 談談我對深拷貝和淺拷貝的理解
- 談談你對Promise的理解Promise
- 談談對中斷的理解
- 談談對BPM的理解(轉)
- 談談對Spring IOC的理解Spring
- MVC、MVP、MVVM,談談我對Android應用架構的理解MVCMVPMVVMAndroid應用架構
- 談談我對 AIGC 趨勢下軟體工程重塑的理解AIGC軟體工程
- 談談對MVC、MVP和MVVM的理解?MVCMVPMVVM
- 談一談對vuex的簡單理解Vue
- 每日一問:談談對 MeasureSpec 的理解
- 談談對IOC及DI的理解與思考
- 面試——談談你對Java 平臺的理解面試Java
- 談談你對前端效能優化的理解前端優化
- 談談我對996.icu的看法996
- 【Java 容器面試題】談談你對HashMap 的理解Java面試題HashMap
- 談一談對vue-router的簡單理解Vue
- Java面試題:請談談對ThreadLocal的理解?Java面試題thread
- 簡單談談我理解的React元件生命週期React元件
- 入Ali的過去一年,談談我對code-review的理解| 掘金年度徵文View
- 【搞定面試官】談談你對JDK中Executor的理解?面試JDK
- 面試——談談你對Java 物件導向思想的理解面試Java物件
- 談談對搜尋技術Elastic Search&Lucene的理解AST
- 淺談對java-GC的理解JavaGC
- 談談我對MySQL+PHP+Flex開發的見解MySqlPHPFlex
- 談談對分散式事務的一點理解和解決方案分散式
- JAVA面試題 請談談你對Sychronized關鍵字的理解?Java面試題Zed
- 第 15 題:談談你對迴流和重繪的理解?
- 【面試普通人VS高手系列】談談你對Seata的理解面試
- GSLB是什麼?談談對該技術的一點理解