使用 Ramda 将多参数函数转换为无点样式

Converting multi-parameter function to point-free style using Ramda

使用 Ramda,出于教育和风格原因,我正在尝试将一个相当大的函数转换为无点函数。

该函数接受 4 个参数,一个 ES6 map,一个接受对象的 domainModel 函数和 returns 一个对象, 一个 key 属性 来标识地图上设置的内容,以及一个 json 属性这是在被 domainModel.

调用后在地图上设置的
const setNewDomainModelOnMap = curry((map, domainModel, key, json) => map.set(key, domainModel(json)));

现在,我已经柯里化了函数以获得一些功能优势,但如果可能的话我想使用无参数版本。我已经成功地在参数较少的函数上采用了无点风格,无法完全找出接近这个的正确角度。

专业化功能

柯里化的全部意义在于它允许您使用绑定的每个参数专门化函数。这使我们能够编写 通用 函数,这些函数可以以多种方式进行专门化

const mult = x => y => x * y
const double = mult (2)
const triple = mult (3)
const negate = mult (-1)

console.log(double(5)) // 10
console.log(triple(5)) // 15
console.log(negate(5)) // -5

你有一个名为 setNewDomainModelOnMap 的函数,它有一个非常专业的 name 但函数本身非常具体 – 没有任何通用之处。

如果您编写了一个 通用 函数,而该函数可以根据您提供的参数专门化,会怎样?

// maybe something liek this would be better
const myfunc = set (someKey, someValue)
const updatedMap = myFunc (oldMap)

横向思维

set 怎么样?

您的函数的 性质 是在地图上设置一个值——该值被某些函数增加的事实 domainModel 并不意味着它具有成为您设置函数的参数

const set = curry((key, value, map) =>
  map.set(key, value)
)

set(someKey, domainModel(json), someMap)
// => Map { ... }

不,如果你的函数不变成嵌套 compose 调用的灾难,你就不能再删除任何点 – 特别是因为你正在包装一个方法 (map.set),这会使保留上下文要复杂得多。


Ramda 同意这很有用

Ramda 实际上有它自己的 set 函数,它在 Lens、一些值和一些对象上运行。

var xLens = R.lensProp('x');

R.set(xLens, 4, {x: 1, y: 2});  //=> {x: 4, y: 2}
R.set(xLens, 8, {x: 1, y: 2});  //=> {x: 8, y: 2}

鉴于此,如果您担心命名冲突,您可能想要命名您的函数 mapSet