若 Function 的各自 Argument 先經過不同 Function 處理過,最後在傳給 Function 的各自 Argument,則可使用 useWith()
使其 Point-free。
Version
macOS Catalina 10.15.4
VS Code 1.43.2
Quokka 1.0.285
Ramda 0.27.0
Functional
import { find, propEq } from 'ramda'
let data = [
{ title: 'FP in JavaScript', price: 100 },
{ title: 'RxJS in Action', price: 200 },
{ title: 'Speaking JavaScript', price: 300 },
]
let f = v => a => find(propEq('price')(v))(a)
f(100)(data) // ?
若我們想根據 price
找資料建立了 f()
,其中第一個 argument 為要搜尋的 v
,第二個 argument 為 a
,再使用 find()
與 propEq()
組合。
Point-free
import { find, propEq } from 'ramda'
let data = [
{ title: 'FP in JavaScript', price: 100 },
{ title: 'RxJS in Action', price: 200 },
{ title: 'Speaking JavaScript', price: 300 },
]
let f = v => find(propEq('price')(v))
f(100)(data); // ?
由於 a
在最後一個 argument,因此可輕易 point-free 掉 a
。
Point-free
import { find, propEq, useWith, identity } from 'ramda'
let data = [
{ title: 'FP in JavaScript', price: 100 },
{ title: 'RxJS in Action', price: 200 },
{ title: 'Speaking JavaScript', price: 300 },
]
let f = useWith(
find, [propEq('price'), identity]
)
f(100)(data) // ?
對於這種超過一個 argument 的 function,若我們想將全部 argument 都 point-free 可以使用 useWith()
,他將回傳一個新的 curried function,且 argument 個數與原本 function 相同。
useWith()
((x1, x2, ...) -> z) -> [(a -> x1), (b -> x2), ...] -> (a -> b -> ... -> z)
建立一個與原 function 的 argument 個數相同的新 function,且各 argument 會先經過 transformer function 處理過再傳給原 function 執行
((x1, x2, ...) -> z)
:原本尚未 curried、尚未 point-free 的 function
[(a -> x1), (b -> x2), ...]
:為 array,有幾個參數就會有幾個 transformer function,新 function 的所有參數,都會經過 transformer function 執行過,結果才會傳給原 function
(a -> b -> ... -> z)
:回傳新 function,且是 curried function
let f = x => a => find(propEq('price')(x))(arr)
let f = useWith(
find, [propEq('price'), identity]
)
要將 f()
重構成 point-free 很簡單:
- 將
find()
放在useWith()
的第一個 argument - 將原本 在
find()
第二個 argument 的propEq('price')
改寫在 array 內 v
不變則使用identity()
如此 v
與 a
兩個 argument 就被幹掉了,成了全部 point-free。
Conclusion
- 若要使用
useWith()
時,建議先還原之前 point-free 掉的 data argument,連其他 argument 與 data argument 一起思考如何 point-free