點燈坊

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

useWith(f, [g, identity]) 與 compose() 等效性

Sam Xiao's Avatar 2020-04-12

當 Point-free 時,常會化簡成 useWith(f, [g, identity]) 這種 pattern,事實上這只是簡單的 compose() 而已。

Version

Ramda 0.27.1

Predicate

import { filter } from 'ramda'

let data = [
  { title: 'FP in JavaScript', price: 100 },
  { title: 'Elm in Action', price: 200 },
  { title: 'Speaking JavaScript', price: 300 }
]

let f = v => filter(x => x.price === v)

f(100)(data) // ?

一個典型的 function 提供 argument 給 predicate。

compose000

Point-free

import { filter, useWith, identity, propEq } from 'ramda'

let data = [
  { title: 'FP in JavaScript', price: 100 },
  { title: 'Elm in Action', price: 200 },
  { title: 'Speaking JavaScript', price: 300 }
]

useWith(
  filter, [propEq('price'), identity]
)(100)(data) // ?

在 Point-free 過程,為了殿出最後一個 argument 為 data,會使用 useWith(f, [t, identity]) 的組合。

compose001

Function Composition

import { filter, compose, propEq } from 'ramda'

let data = [
  { title: 'FP in JavaScript', price: 100 },
  { title: 'Elm in Action', price: 200 },
  { title: 'Speaking JavaScript', price: 300 }
]

compose(filter, propEq('price'))(100)(data)

最後一個 identity() 其實是虛的,只是配合 useWith() 需要而已,事實上可用 compose() 加以組合即可。

compose002

Conclusion

  • 若是由 data 思考常著重於 Point-free,而沒發現僅僅是簡單的 Function Compostion 而已
  • 可將 useWith(f, [g, identity]) 視為 pattern,當重構看到這樣的組合時,再使用 compose() 取代

Reference

Ramda, compose()
Ramda, useWith()