首頁>Club>
5
回覆列表
  • 1 # 小精靈zx

    Monad

      

      A monad is just a monoid in the category of endofunctors

      the category of endofunctors是自函子endofunctor的範疇(category),Monad是自函子範疇中的Monoid。

      前面我們已經瞭解函子的對映原理,自函子可以理解為對映範疇C到另外一個範疇C。那麼自函子的範疇是什麼意思?是基於自函子的新範疇嗎?經過查詢此句原出處: Here it is in context,原文是:

      All told, a monad in X is just a monoid in the category of endofunctors of X, with product × replaced by composition of endofunctors and unit set by the identity endofunctor.

      確實是基於範疇X的新範疇,這個新範疇看成是endofunctors on X。範疇X之上的範疇,這個新範疇的元素物件是自函子endofunctor,談到範疇就要想到元素物件和態射,那麼其態射是什麼呢?

      前面我們解釋函子funtor工作原理時,有一句:"3.壓平這兩層集合,組合所有的結果",這個組合方式是一種自然變換natural transformation,屬於新範疇的態射,因為態射有份兩種:組合態射和元identitiy,自然變化就要對分別對X範疇中這兩種進行轉換。

      所以,Monad工作原理包含兩個部分:對原範疇組合成新的範疇,這個範疇對於Monad來說必須是么半群Monoid,可以認為Monad是一系列自函子的組合,這種組合是一種轉換,轉換的結果是Monoid。

      Monad有以下特徵:

    Monad是一種定義將函式(函子)組合起來的結構方式。(monoid是定義元素物件組合起來的結構方式。如果元素物件是特殊種類:函式(函子),那麼它可能是Monad)這些組合的方法都是符合結合律的有一個特殊么元,能夠和任何元素組合,導致的結果是不改變這些元素。

      關鍵對最後一點么元講解一下,以為什麼需要Monad?一文中案例為說明,假設有兩個數字a和b相加,這裡a和b 可能為空,Java 程式碼如下:

    int try_to_add_numbers( Integer a, Integer b ) { return a + b; }

      如果a 和b非空,那麼這個方法將會返回它們的總數,但是如果其中有一個是空的,我們會得到NullPointerException錯誤,呼叫客戶端得到這個錯誤必須去處理它。而函式的定義是有一個輸入型別和一個輸出型別,現在又跑出第三種類型Exception,很顯然Exception是和輸入輸出型別不屬於同一個範疇,這就不符合封閉運算了。

      那麼我們使用一個么元,比如Optional來封裝結果,這樣就能保證不丟擲Exception,而是將Exception錯誤透過輸出結構輸出,這種結果分兩種,要麼是空,要麼是有值,如果是有值,開啟它就能獲得真正的計算結果。我們使用Optional與結果值結合,但是不會改變這個結果值型別。具體可見: Java8中option實現Monad

      總體來說:Monoid是元素物件的組合的範疇,如果這種元素物件是函式或函子(也可能是Pipe,這就複雜了去了 ),那麼Monad是自函子的組合範疇,Monad也是一種特殊的Monoid子集。

      如果你對大資料Hadoop等比較熟悉,map/reduce其實也是一個Monad。

      最後我們用簡單大白話(不精確有助於理解)翻譯一下Monad的英文定義:A monad is just a monoid in the category of endofunctors,monad只不過也是一種特殊情況下的monoid,特殊在哪裡呢?就是自己對自己進行轉換的集合而已。

  • 中秋節和大豐收的關聯?
  • 如何看待華盛頓對美國的歷史貢獻?