點燈坊

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

使用 converge() 組合 Function

Sam Xiao's Avatar 2020-04-11

converge()useWith() 非常類似,useWith() 是新 Function 的 Arity 與 Array 的 Length 相等;而 converge() 是 Array 中所有 Function 的最大 Arity 決定。

Version

Ramda 0.27.1

converge()

converge()
((x1, x2, …) → z) → [((a, b, …) → x1), ((a, b, …) → x2), …] → (a → b → … → z)
建立一個新 funtion,其 arity 由 array 內所有 function 的最大 arity 決定
會先經過 branching function 運算,再將結果傳給 converging function 執行

((x1, x2, …) → z):converging function,最後要收斂的 function

[((a, b, …) → x1), ((a, b, …) → x2), …]:為一 array,其中 ((a, b, …) → x1) 稱為 branching function,converging function 的 arity 會與 array 內 branching function 數量相等,新 function 的所有參數會先經過各 branching function 執行,結果才會傳給 converging function 執行

(a → b → … → z):回傳新的 curried function,其 arity 由 branching function 中最大 arity 決定

Single Argument

let data = {
  name: 'iPhone',
  price: 10000,
  discount: 0.9,
}

let f = o => o.price - o.discount

f(data) // ?

當只有一個 argument (通常為 Object),接下來要做的就是要讀取其 property,正常會使用 .,但 . 必須搭配 argument,儘管是最後一個 argument 也無法 Point-free。

converge000

Object Destructuring

let data = {
  name: 'iPhone',
  price: 10000,
  discount: 0.9,
}

let f = ({price, discount}) => price - discount

f(data) // ?

ES6 雖有 object destructuring 可直接在 parameter 將 object 分解,但仍無法 Point-free。

converge002

converge()

import { converge, subtract, prop } from 'ramda'

let data = {
  name: 'iPhone',
  price: 10000,
  discount: 0.9,
}

converge(
  subtract,[prop('price'), prop('discount')]
)(data) // ?

從另外一個角度觀察,我們發現最終要執行 -,且 data.pricedata.discount 都要讀取 property,且為單一 argument ,符合 converge() 格式要求。

  • 使用 subtract() 取代 -
  • 使用 prop() 取代 .

若改用 converge(),可先透過 branching function prop() 得到 property 資料,在各自傳給 subtract() 的第一個與第二個 argument。

由於 converge() 會回傳以 subtract() 回傳值為 argument 的 function,因此可將原本 o argument 給 Point-free 。

argument 為 object 是 converge() 最常見用法,可視為 pattern 使用

converge003

converge001

Conclusion

  • converge() 看似複雜,而其使用時機是當 一個 argument 同時被數個 function 使用,最後再將結果交給同一個 function 執行時,可使用 converge() 整合這些 function,並將最後執行的 function 成為 converging function,而使用 argument 的數個 function 成為 branching function
  • converge()useWith() 看似相似,但 converge() 是每個 branching function 處理所有 argument,而 useWith() 是每個 function 各自處理 argument

Reference

Ramda, converge()