在組合 Function 時,實務上常常遇到期望的 Signature 與 Ramda 所提供的 Function 不一樣,此時可利用 flip()
加以改變。
Version
macOS Catalina 10.15.2
VS Code 1.41.1
Quokka 1.0.274
Ramda 0.26.1
Currying
let fn = discount => price => price - discount - 10
fn(20)(100) // ?
fn()
第一個 argument 為 discount
,第二個 argument 為 price
,除此之外,還在 function body 內多扣了 10
元。
比較特別的是 price
是放在最後一個 argument。
這個 function 就功能而言 100% 沒問題,但能否更進一步 point-free 呢 ?
Functional
import { pipe, negate, add, flip } from 'ramda'
let fn = pipe(
negate,
flip(add)(-10),
add
)
fn(20)(100) // ?
由於第一個 argument 是 discount
且為 -
,因此先使用了 negate()
。
接下來要處理 -10
,由於 add()
的第一個 argument 要傳入 被減數
,也就是 negate()
所計算結果,因此不能簡單使用 add(-10)
,因為 -10
該是 減數
。
我們發現期望的 add()
signature 與現實剛好相反 !!
因此特別使用 flip(add)
將 add()
的 signature 反轉,再傳入 -10
,最後再 add()
迎接 price
。
flip()
((a, b, c, …) → z) → (b → a → c → … → z)
將 function 的第一個 argument 與第二個 argument 對調,順便 currying
((a, b, c, …) → z)
:原來 function
(b → a → c → … → z)
:回傳 argument 對調過的 curried function
__
import { pipe, negate, add, __ } from 'ramda'
let fn = pipe(
negate,
add(__)(-10),
add
)
fn(20)(100) // ?
若你覺得 flip()
可讀性不高,也可改用 __
,視覺上提供前一個 function 所傳入的 placeholder。
Conclusion
flip()
在實務上常常使用,尤其在計算類的 function 上flip()
與__()
各有愛好者,可依可讀性自行選擇