Haskell 提供多種 Operator 組合 Function,可視需求與可讀性選擇使用。
Version
Haskell for Mac 1.8.2
map()
f x = map(*2)(map(+1) x)
f [1, 2, 3]
若要使 List 的每個 element 先 +1
,最後再加 *2
,可直接搭配兩次 map()
完成。
$
f x = map(*2) $ map(+1) x
f [1, 2, 3]
傳統 Function Composition 會造成 ()
爆炸,Haskell 提供了 $
,則無論多少層 f(x)
都只有一層 $
。
&
import Data.Function
f x = x & map(+1) & map(*2)
f [1, 2, 3]
若你覺得 $
的 由右至左
不易閱讀,而想 由左至右
,可改用 Data.Function
的 &
。
.
f = map(*2) . map(+1)
f [1, 2, 3]
若想使 f()
能 Point-free,可使用 .
將 map(+1)
與 map(*2)
加以組合,唯 .
為 由右至左
。
>>>
import Control.Category
f = map(+1) >>> map(*2)
f [1, 2, 3]
若你覺得 .
的 由右至左
不易閱讀,而想 由左至右
,可改用 Control.Category
的 >>>
。
Composition Law
import Control.Category
transform = (+1) >>> (*2)
f = map transform
f [1, 2, 3]
List 是 Functor,因此遵循 composition law:
fmap f . fmap g = fmap (f . g)
第 3 行
transform = (+1) >>> (*2)
因此可將 (*2)
與 (+1)
使用 >>>
組合起來成 transform()
。
第 5 行
f = map transform
最後只要使用一次 map()
即可。
Conclusion
- Haskell 的
&
相當於 F# 的|>
- Haskell 的
.
相當於 Ramda 的compose()
,而>>>
相當於 Ramda 的pipe()