點燈坊

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

使用 over() 藉由 Lens 新增修改 Property

Sam Xiao's Avatar 2021-04-22

set()over() 都可使用 Lens 新增修改 Property,唯 set() 是傳入值,而 over() 是傳入 Function。

Version

Ramda 0.27.1

over()

import { ifElse, has, over, lensProp, inc, set } from 'ramda'

let incCount = ifElse(
  has('count'),
  over(lensProp('count'), inc),
  set(lensProp('count'), 1)
)

incCount({}) // ?          
incCount({ count: 1 }) // ? 

若傳入 Object 有 count property 則修改其值遞增,若無則建立 count property 並設定初始值為 1

第 3 行

let incCount = ifElse(
  has('count'),
  over(lensProp('count'), inc),
  set(lensProp('count'), 1)
)

使用 ifElse() 組合出 incCount()

  • has('count'):判斷是否有 count property
  • over(lensProp('count'), inc):若有則透過 Lens 修改 property,注意第二個 argument 是 inc() 而非定值
  • set(lensProp('count'), 1):若無則透過 Lens 新增 property,注意第二個 argument 是定值而非 function

over()
Lens s a → (a → a) → s → s
透過 function 使用 lens 新增修改 object 指定 property

  • Lens s a:傳入 property 的 Lens
  • (a -> a):傳入改變 property 的 function
  • s:傳入 Object
  • s:回傳新 Object

over000

assoc()

import { ifElse, has, over, lensProp, inc, assoc } from 'ramda'

let incCount = ifElse(
  has('count'),
  over(lensProp('count'), inc),
  assoc('count', 1)
)

incCount({}) // ?          
incCount({ count: 1 }) // ? 

第 3 行

let incCount = ifElse(
  has('count'),
  over(lensProp('count'), inc),
  assoc('count', 1)
)

若改變 property 不要求 function,其實 set()assoc() 功能相同。

over001

Conclusion

  • set()assoc() 功能相同,唯 set() 必須搭配 Lens
  • set()over() 都能藉由 Lens 新增修改 property,唯 set() 傳入定值,而 over() 可傳入 function

Reference

Ramda, over()