點燈坊

失くすものさえない今が強くなるチャンスよ

使用 map 將兩個 Function 綁定

Sam Xiao's Avatar 2021-07-16

map 是 FP 最具代表性的 Higher Order Function,僅管大部分 FP 原則都沒搞得很懂,但 map 一定都用得很熟;大部分人都將 map 用在 Array,但因為 First Class Function,map 也能將兩個 Function 綁定。

Version

Ramda 0.27.1

Imperative

let f = x => -(x + 1)

f (1) // ?

f 將兩個 argument 相加並取負號,可使用 +- operator 實現。

這個 function 就功能而言 100% 沒問題,但能否更進一步 Point-free 呢 ?

map000

pipe

import { pipe, inc, negate } from 'ramda'

pipe (inc, negate) (1) // ?

直覺會使用 pipe 組合 incnegate

map001

compose

import { compose, inc, negate } from 'ramda'

compose (negate, inc) (1) // ?

既然能用 pipe 就能使用 composepipe由左到右 執行,而 compose由右向左 執行。

map002

map

import { map, inc, negate } from 'ramda'

map (negate, inc) (1) // ?

compose 寫法長得好像喔,只是將 compose 換成 map,難道 map 等於 compose ?

map
Functor f => (a → b) → f a → f b
傳入 unary function 改變 Functor 內部 value

這是 map 的定義,注意 Ramda 從來都沒說第二個 argument 是 Array,而是說它是個 Functor。

Array 是 Functor,function 也是 Functor,所以也能將 function 用在 map

簡單來說,支援 map 的 Object 就是 Functor,而 function 本身就是一種 mapping,所以 function 可以視為 Functor

使用 mapincnegate 綁定相當於使用 composeincnegate 組合。

事實上在 map 官網,最後一句話就是 Also treats functions as functors and will compose them together.,只可惜微言大意,並沒有更進一步的範例,因此很容易忽略

map003

Conclusion

  • pipe由左向右,而 compose由右向左,兩者可等價替換
  • 若只 compose 兩個 function,可等價使用 map 替換,因為 function 也是 Functor,使用 map 將兩個 function 綁定,等效於使用 compose 組合兩個 function

Reference

Ramda, map