針對提到的第一點,我想要針對我的觀念做一點釐清跟討論。
我今天認真的看了一下 讀書會 第二場,跟一些 Learn You a Haskell for Great Good
的內容。
我發現 haskell 裡的所有的 function 都只接受一個 param,並回傳一個function 接受下一個 param。
其實在 oo 中,可以 combine 起來,變成一個 function,接受兩個 parameter。
另外因為語法及特性的不同,所以其實 oo 中的 monad 跟 haskell 中的 monad,語法不會完全一樣。
我在實作的時候,是看著 haskell
中的 monad (>>=)
來實作。
它的定義是 M a -> (a -> M b) -> M b
因此,我要先做一個 bbind()
對應 接受 M a的 function ,它會回傳一個接受 callback function (a -> M b)
的 function。
再我的實作中是 回傳 operate
function。
在 TS 的實作中,因為 bind
是屬於 Box
的 instance,
所以事實上,接受 M a
的這個 function
是不需要實作的。
會有這個差別,是因為 haskell
的幾乎所有動作,都是透過 function
完成的。
對於以上的疑問,需要先認清,class 中的 function parameter其實是語法糖。 它會塞本身當作第一個 param,並且關聯到 this 關鍵字。 因此以這點來說,幾乎只是語法上的差別。
觀察 Monad 的 instance Maybe
,會發現,
事實上 Monad 的實作,其實是在做 curried / uncarried
的動作:
instance Monad Maybe where
return x = Just x
Just x >>= f = f x
Nothing >>= _ = Nothing
在 haskell 中,因為有 colusure 的特性,所以一個接受多個參數的 function, 可以使用 curried 將它變成多個 function。 oo 實作中,可以適時的 uncurry function,重點是實現特性。
-
在 haskell 中,所有的 function 都是 curried function、接受一個 input,回傳下一個 function。
-
在 oo 中,可以依情況做
uncurry
的動作。haskell 中的所有function都是 curry function。
如 (>>=) :: M a -> (a->M b) -> M b
bind 的定義,在 ts 中可能可以實作成:
M<a> .bind((a) => M<b>);
重點是符合 monad 的特性:傳入一個 接收 a,並回傳 M<b>
的function,並且最後回傳 M<b>
。
- 在使用 oo 實作haskell 的 typeclass (如
monad
)時,重點是實現 typeclass 的動作(function
)展現的特性。
理解 uncurried / curried / clousure function 之間的關係,以及 oo 中,成員函數的實際行為後,typeclass 就幾乎可以視為 java 的 interface了。
-
以實作來說,
bind(M a)
->operate: a -> M b
可以uncurried 成一個函式,bind(operate: a => Mb)
。因為 oo 中的所有函式成員,都可以使用本身的屬性。 -
pure functional programming 的一個非常必要的條件是,不可以造成副作用,因此不會有 「指令」(no for, no value asignment ...)。
以上次的實作來說, operator 不該 return 自己,而應該產生一個新的 Box instance。
稍微針對新的理解,修改了一下敘述。
主要是 將 curry / uncurry / closure 的觀念 與「函式組合」分開,它們有不同定義,
oo 的 函式成員可以視為語法糖。
所有的 function 都可以視為一個value、所有東西都可以是 function。
這些觀念再建立起來後,haskell 的 type class 其實就沒有這麼不好懂了。