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。
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。
converge()
import { converge, subtract, prop } from 'ramda'
let data = {
name: 'iPhone',
price: 10000,
discount: 0.9,
}
converge(
subtract,[prop('price'), prop('discount')]
)(data) // ?
從另外一個角度觀察,我們發現最終要執行 -
,且 data.price
與 data.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 使用
Conclusion
converge()
看似複雜,而其使用時機是當一個 argument
同時被數個 function 使用,最後再將結果交給同一個 function 執行時,可使用converge()
整合這些 function,並將最後執行的 function 成為 converging function,而使用 argument 的數個 function 成為 branching functionconverge()
與useWith()
看似相似,但converge()
是每個 branching function 處理所有 argument,而useWith()
是每個 function 各自處理 argument