點燈坊

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

使用 compose() 組合 Lens

Sam Xiao's Avatar 2021-04-23

Lens 本質就是 Function,因此也可使用 compose() 組合小 Lens 成為大 Lens。

Version

Ramda 0.27.1

Object

import { lensProp, over, inc, compose } from 'ramda'

let data = {
  title: 'FP in JavaScript',
  price: {
    Amazon: 100,
    eBay: 200
  }
}

let amazon = compose(
  lensProp('price'),
  lensProp('Amazon')
)

over(amazon, inc, data) // ?

第 3 行

let data = {
  title: 'FP in JavaScript',
  price: {
    Amazon: 100,
    eBay: 200
  }
}

data 為 Nested Object,想將 price 下的 Amazon 遞增為 101

11 行

let amazon = compose(
  lensProp('price'),
  lensProp('Amazon')
)

使用 compose() 組合出 amzon Lens:

  • lensProp('price'):建立 price Lens
  • lensProp('Amazon'):建立 Amazon Lens

16 行

over(amazon, inc, data) // ?

使用 over()amazon Lens 遞增。

compose000

Object Array

import { lensProp, lensIndex, over, toUpper, compose } from 'ramda'

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

let title = compose(
  lensIndex(0),
  lensProp('title')
)

over(title, toUpper, data) // ?

第 3 行

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

data 為 Object Array,想將第一筆資料的 FP in JavaScript 全變成大寫。

第 9 行

let title = compose(
  lensIndex(0),
  lensProp('title')
)

使用 compose() 組合出 title Lens:

  • lensIndex(0):建立 price Lens
  • lensProp('title'):建立 Amazon Lens

compose001

Conclusion

  • 除了能使用 lensPath() 一次建立 Lens 外,亦可使用 compose() 組合小 Lens