如何传递多个参数以与 Ramda.JS 组合
How to pass multiple arguments to compose with 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])
当我调用 makeThing
时,我首先将 5
传递给它。 makeArrayFromNum
接受 5
并且一切顺利......也就是说,直到 concat
。 concat
returns 一个函数。因为 concat
有 2 个参数,我希望它返回到我原来的参数列表,并找到尚未使用的 [9]
。它没有。
This 应该是 Ramda REPL 的 link,使用我上面粘贴的相同代码。但至少你可以 运行 它在那里。
谢谢
更新
上面的代码片段不起作用,但我写了它是因为它以一种清晰的方式展示了我想要实现的目标。由于它引起了错误的注意,我添加了两个更多的功能代码片段,它们也展示了我的目标,但是以一种不清楚和不简洁的方式。
由于评论中有人说无法使用 compose
因为 compose
只接受一元函数,我觉得我应该提供 a 我想出的解决方案来帮助澄清我的问题。
希望这有助于其他人回答我的问题。
const makeThing = compose(
map(multByTwo),
useWith(
concat,
[
compose(
map(multByTen),
makeArrayFromNum
),
identity
]
)
)
makeThing(5, [9])
还有一个给后代的:
const makeThing = compose(
map(multByTwo),
converge(
concat,
[
compose(
map(multByTen),
makeArrayFromNum,
head
),
tail
]
)
)
我原来的问题仍然成立。上述解决方案在功能上获得了什么,但它们缺乏清晰性和简洁性。
它不起作用,因为 compose
is, quite literally, just composing the functions。这意味着 所有 参数被传递给 last/rightmost 函数,然后该函数的 return 值被传递给列表中的下一个函数,依此类推在。因此,您的 makeThing
函数本质上是这样的:
const makeThing = (...params) => map(multByTwo)(concat(map(multByTen)(makeArrayFromNum(...params))))
这意味着 makeThing(5, [9])
转换为以下调用:
map(multByTwo)(concat(map(multByTen)(makeArrayFromNum(5, [9]))))
请注意 concat
仅使用一个参数调用,但它需要两个参数。由于 Ramda 函数是自动柯里化的,不完整的 concat
return 是另一个需要第二个参数的函数。由于没有传递第二个参数,因此事情在那时就崩溃了。
那你该怎么做呢?你需要的是这样的:
const makeThing = (a, b) => map(multByTwo)(concat(map(multByTen)(makeArrayFromNum(a)), b))
// alternatively...
const makeThing = (a, b) => map(multByTwo)(concat(map(multByTen)(makeArrayFromNum(a)))(b))
尝试一下,您会发现它提供了预期的输出。不幸的是,这并不能直接转换回 compose
;你能得到的最接近的是:
const makeThing = (a, b) => compose(
map(multByTwo),
concat(b),
map(multByTen),
makeArrayFromNum
)(a)
您得到的结果很接近,但项目相反。也许有一些 Ramda 函数可以用来处理这个问题,但我不知道所有的函数,所以我无能为力。
首先可以将以下函数转化为:
num => [num]
等于 R.of
num => num * 10
等于 R.multiply(10)
num => num * 2
等于 R.multiply(2)
我可以看到两个选项:
有一个函数returns另一个函数
如你所见,函数组合是"hardcoded"到num参数。注意我还稍微修改了你原来的函数组合
const makeThingFn = num =>
compose(
map(multiply(2)),
flip(prepend)([num]),
multiply(10));
const makeThing = makeThingFn(9);
makeThing(5); //=> [100, 18]
使用镜头
这样你可以直接传递你的数组,但让函数组合对特定索引进行操作:
const makeThing =
compose(
map(multiply(2)),
over(lensIndex(0), multiply(10)));
makeThing([5, 9]); //=> [100, 18]
我正在使用 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])
当我调用 makeThing
时,我首先将 5
传递给它。 makeArrayFromNum
接受 5
并且一切顺利......也就是说,直到 concat
。 concat
returns 一个函数。因为 concat
有 2 个参数,我希望它返回到我原来的参数列表,并找到尚未使用的 [9]
。它没有。
This 应该是 Ramda REPL 的 link,使用我上面粘贴的相同代码。但至少你可以 运行 它在那里。
谢谢
更新
上面的代码片段不起作用,但我写了它是因为它以一种清晰的方式展示了我想要实现的目标。由于它引起了错误的注意,我添加了两个更多的功能代码片段,它们也展示了我的目标,但是以一种不清楚和不简洁的方式。
由于评论中有人说无法使用 compose
因为 compose
只接受一元函数,我觉得我应该提供 a 我想出的解决方案来帮助澄清我的问题。
希望这有助于其他人回答我的问题。
const makeThing = compose(
map(multByTwo),
useWith(
concat,
[
compose(
map(multByTen),
makeArrayFromNum
),
identity
]
)
)
makeThing(5, [9])
还有一个给后代的:
const makeThing = compose(
map(multByTwo),
converge(
concat,
[
compose(
map(multByTen),
makeArrayFromNum,
head
),
tail
]
)
)
我原来的问题仍然成立。上述解决方案在功能上获得了什么,但它们缺乏清晰性和简洁性。
它不起作用,因为 compose
is, quite literally, just composing the functions。这意味着 所有 参数被传递给 last/rightmost 函数,然后该函数的 return 值被传递给列表中的下一个函数,依此类推在。因此,您的 makeThing
函数本质上是这样的:
const makeThing = (...params) => map(multByTwo)(concat(map(multByTen)(makeArrayFromNum(...params))))
这意味着 makeThing(5, [9])
转换为以下调用:
map(multByTwo)(concat(map(multByTen)(makeArrayFromNum(5, [9]))))
请注意 concat
仅使用一个参数调用,但它需要两个参数。由于 Ramda 函数是自动柯里化的,不完整的 concat
return 是另一个需要第二个参数的函数。由于没有传递第二个参数,因此事情在那时就崩溃了。
那你该怎么做呢?你需要的是这样的:
const makeThing = (a, b) => map(multByTwo)(concat(map(multByTen)(makeArrayFromNum(a)), b))
// alternatively...
const makeThing = (a, b) => map(multByTwo)(concat(map(multByTen)(makeArrayFromNum(a)))(b))
尝试一下,您会发现它提供了预期的输出。不幸的是,这并不能直接转换回 compose
;你能得到的最接近的是:
const makeThing = (a, b) => compose(
map(multByTwo),
concat(b),
map(multByTen),
makeArrayFromNum
)(a)
您得到的结果很接近,但项目相反。也许有一些 Ramda 函数可以用来处理这个问题,但我不知道所有的函数,所以我无能为力。
首先可以将以下函数转化为:
num => [num]
等于R.of
num => num * 10
等于R.multiply(10)
num => num * 2
等于R.multiply(2)
我可以看到两个选项:
有一个函数returns另一个函数
如你所见,函数组合是"hardcoded"到num参数。注意我还稍微修改了你原来的函数组合
const makeThingFn = num =>
compose(
map(multiply(2)),
flip(prepend)([num]),
multiply(10));
const makeThing = makeThingFn(9);
makeThing(5); //=> [100, 18]
使用镜头
这样你可以直接传递你的数组,但让函数组合对特定索引进行操作:
const makeThing =
compose(
map(multiply(2)),
over(lensIndex(0), multiply(10)));
makeThing([5, 9]); //=> [100, 18]