目前我們介紹了兩個型別,分別是Option與Either,操作上相當於隔著一層容器對裡面的資料做操作,在FP的世界裡面設計了各種不同的型別,但都具有這種“容器”的概念,在haskell中稱為monad
A monad is a container type together with a few methods defined on it.
我們稍微歸納幾種對容器內值的操作
放入容器
我們會需要值放到容器裡,比如說將數字放入集合,把int放入nullable,在前面的例子我會用工廠方法,對應到FP中有return,可以表示成T → C<T>
容器內映射
Map跟Bind的差別在於,一個是對於容器內元素的操作,一個會將元素提升
Map:C<T> → C<R>
,接受的函數為 T → R
Bind:C<T> → C<R>
,接受的函數為 T → C<T>
拿出容器
C<T> → R
,在前面直接用pattern match解構
對於Monad的Return與Bind會滿足一些條件,如果我們對Bind中再套嵌Return的話就會得到本身自己
var s = Option.Some(1);
s.Bind(x => Option.Some(x));
// Some(1)
如果我們先做Return再做Bind,就相當於直接做Bind中的函數
var s = 1;
Option.Some(s).Bind(x => Option.Some(x+1)) = Some(2);
另外就是結合律,連續兩個Bind可以先將裡面的函數先組合
var s = Option.Some("1");
s.Bind(int.Parse)
.Bind(x=> Option.Some(x+1));
// Some(4)
s.Bind(x => Option.Some(int.Parse(x) + 1))
// Some(4)
在FP中對於這種隔著容器對資料做運算的技巧很重要,容器通常具有某些特徵,透過這些特徵賦予資料某些能力,進而達到我們需要的結果,像是Either就讓我們有對不同輸出值對應的能力。