點燈坊

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

使用 map 將兩個 Function 綁定

Sam Xiao's Avatar 2021-07-16

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

Version

Sanctuary 3.1.0

Imperative

let data = 1

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

f (data) // ?

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

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

compose000

pipe

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

let data = 1

pipe ([inc, negate]) (data) // ?

直覺會使用 pipe 組合 incnegate

compose001

compose

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

let data = 1

compose (negate) (inc) (data) // ?

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

compose002

map

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

let data = 1

map (negate) (inc) (data) // ?

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 組合。

compose003

Conclusion

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

Reference

Sanctuary, map