Cap*_*ate 1 javascript ramda.js
我正在使用 Ramda.js,并且正在努力完成一项简单的任务。有人可以告诉我:1)为什么它不起作用,2)我怎样才能使它起作用
考虑以下代码:
// Defined in utils.js
const makeArrayFromNum = num => [num]
const multByTen = num => num * 10
const multByTwo = num => num * 2
const makeThing = compose(
map(multByTwo),
concat,
map(multByTen),
makeArrayFromNum
)
// Otherfile.js
// import makeThing from .......
// Call it from a different file (does not share scope with above things)
// ---------------
// Expect to get back: [100, 18] because:
// 1) 5 -> makeArrayFromNum -> [5]
// 2) [5] -> map(multByTen) -> [50]
// 3) [50] -> concat (Still needs one arg, so pulls in [9]) -> [50, 9]
// 4) [50, 9] -> map(multByTwo) -> [100, 18]
makeThing(5, [9])
Run Code Online (Sandbox Code Playgroud)
当我调用 时makeThing,我首先传递5给它。makeArrayFromNum接受5,一切都会顺利进行……也就是说,直到concat。concat返回一个函数。因为concat需要 2 个参数,所以我希望它返回到我的原始参数列表,并找到[9]尚未使用的参数。它不是。
这应该是 Ramda REPL 的链接,与我上面粘贴的代码相同。但至少你可以在那里运行它。
谢谢
更新
上面的代码片段不起作用,但我编写了它,因为它清楚地演示了我想要实现的目标。由于它吸引了错误的注意力,我添加了两个更多的功能代码片段,它们也证明了我的目标,但以一种不清楚且不简洁的方式。
由于评论中有人说这是不可能的,compose因为compose只接受一元函数,所以我觉得我应该提供一个我想出的解决方案来帮助澄清我的问题。希望这有助于其他人回答我的问题。
const makeThing = compose(
map(multByTwo),
useWith(
concat,
[
compose(
map(multByTen),
makeArrayFromNum
),
identity
]
)
)
makeThing(5, [9])
Run Code Online (Sandbox Code Playgroud)
还有一个留给后人的:
const makeThing = compose(
map(multByTwo),
converge(
concat,
[
compose(
map(multByTen),
makeArrayFromNum,
head
),
tail
]
)
)
Run Code Online (Sandbox Code Playgroud)
我原来的问题仍然存在。上述解决方案在功能上有所收获,但缺乏清晰度和简洁性。
首先可以将以下函数转换如下:
num => [num]等于R.ofnum => num * 10等于R.multiply(10)num => num * 2等于R.multiply(2)我可以看到两个选项:
有一个返回另一个函数的函数
正如您所看到的,函数组合被“硬编码”到num参数。请注意,我还稍微修改了您原来的函数组合
const makeThingFn = num =>
compose(
map(multiply(2)),
flip(prepend)([num]),
multiply(10));
const makeThing = makeThingFn(9);
makeThing(5); //=> [100, 18]
Run Code Online (Sandbox Code Playgroud)
使用镜片
这样您就可以直接传递数组,但让函数组合对特定索引进行操作:
const makeThing =
compose(
map(multiply(2)),
over(lensIndex(0), multiply(10)));
makeThing([5, 9]); //=> [100, 18]
Run Code Online (Sandbox Code Playgroud)