點燈坊

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

使用 invoker() 將 Instance Method 轉成 Free Function

Sam Xiao's Avatar 2020-07-27

ECMAScript 的 Array.prototypeString.prototypeObject.prototype … 都有很豐富 Instance Method 可用,唯這些 Method 都是以 OOP 形式提供,不方便 Function Pipeline,可使用 Ramda 的 invoker() 將其轉成 Free Function。

Version

macOS Catalina 10.15.6
VS Code 1.47.2
Quokka 1.0.309
Ramda 0.27.0

fill()

let data = [1, 2, 3]

data.fill(0, 1, 2) // ?
data.fill(0, 1) // ?

Array.prototype 提供了 fill(),可在指定 index 填滿指定 value。

若最後一個 argument 省略,則表示填滿到最後。

invoker000

invoker()

import { invoker } from 'ramda'

let data = [1, 2, 3]

let fill = invoker(3)('fill')

fill(0)(1)(2)(data) // ?

Array.prototype.fill() 雖然好用,可惜是以 OOP 形式提供,data 並不是在最後一個 argument,因此很難 Function Pipeline。

可使用 Ramda 的 invoker() 將 instance method 轉成 free function,並將 data 改成最後一個 argument。

invoker()
Number → String → (a → b → … → n → Object → *)
將 instance method 轉成 free function

Number:新 function 的 arity 個數,不包含最後一個 data argument

String:method 名稱

(a → b → … → n → Object → *):回傳新 function,已經自動 curry

invoker001

import { invoker } from 'ramda'

let data = [1, 2, 3]

let fill = invoker(3)('fill')
let fill_ = invoker(2)('fill')

fill(0)(1)(Infinity)(data) // ?
fill_(0)(1)(data) // ?

ECMAScript 有 optional argument 概念,但 Ramda 則無,若想將最後一個 end argument 省略,有兩種方式:

  • 一樣使用 invoker(3),但必須明確提供 Infinity
  • 只使用 invoker(2),會自動提供 optional argument

invoker002

Conclusion

  • Ramda 並沒有提供 fill(),但可自行使用 invoker() 將 instance method 轉成 free function
  • 隨著 ECMAScript 進步會有更多 instance method 出現,可自行使用 invoker() 轉成 free function,方便 Function Pipeline
  • 若要將 static method 轉成 free function,則可使用 bind()

Reference

Ramda, invoker()
Ramda, bind()