使用 javascript 中的相同参数组成链式函数
compose chained functions using the same parameter in javascript
我正在尝试更好地理解 ramda.js 中的功能组合,目前 class 中有一个方法如下所示:
const replace = (newItem) => function3(function1(newItem).function2(newItem));
我在 ramda.js 中知道一个更简单的函数,例如
const replace = (newItem) => function2(function1(newItem));
你可以这样写
const replace = compose(function2, function1);
是否有类似的方法可以使用函数组合/应用程序或其他 ramda.js 辅助方法对初始函数执行相同的操作?
Ramda 有两个函数可以帮助解决这个问题。比较标准的是lift
。许多函数式语言都有这个概念。考虑它的一种方法是,它提升了一个对值进行操作的函数,以创建一个对这些值的 容器 进行操作的函数:
add(3, 5) //=> 8
lift(add)([3], [5]) //=> [8]
函数也可以看作是值的容器。 return 给定类型值的函数可以被视为该类型的容器。
因此我们可以让您的 function3
不是对值进行操作,而是对这些值的容器进行操作,然后将其提供给这些函数的输入。这是一个以数组作为容器的示例:
const function1 = newItem => `function1(${newItem})`
const function2 = newItem => `function2(${newItem})`
const function3 = (v1, v2) => `function3(${v1}, ${v2})`
const combine = R.lift(function3)(function1, function2)
console.log(combine('foo')) //=> "function3(function1(foo), function2(foo))"
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.js"></script>
不太标准的函数是converge
。这仅关注功能,而不关注任意容器。在这种情况下它的工作原理类似。该函数是一次性创建的,而不是 lift
的两次创建。这意味着初始函数需要包装在一个数组中:
const function1 = newItem => `function1(${newItem})`
const function2 = newItem => `function2(${newItem})`
const function3 = (v1, v2) => `function3(${v1}, ${v2})`
const combine = R.converge(function3, [function1, function2])
console.log(combine('bar')) //=> "function3(function1(bar), function2(bar))"
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.js"></script>
converge
仅适用于函数,但它可以与多元函数一起使用。 lift
仅适用于一元的。 converge
是一个特定于 Ramda 的函数。我没有在其他地方看到它。所以,如果 lift
适合你,我建议你选择它。
所以你的问题是怎么写
function1(input).function2(input)
以实用的方式。如果我是正确的,方法如下:
首先让我们创建一个函数method
,它会为我们提供绑定到该对象的对象的方法:
const method = R.curry((name, object) => R.bind(object[name], object))
使用这个函数,我们可以将表达式重写为
method('function2', function1(input))(input)
但我们想要更干净、更可重用的东西,对吧?所以让我们做一些重构
method('function2', function1(input))(input)
method('function2')(function1(input))(input)
R.pipe(function1, method('function2'))(input)(input) // or use R.compose
R.converge(R.call, [
R.pipe(function1, method('function2')),
R.identity
])(input)
现在我们可以像这样定义我们的函数combine
const combine = (fn, name) =>
R.converge(R.call, [
R.pipe(fn, method(name)),
R.identity
])
表达式变为
combine(function1, 'function2')(input)
我希望我的解释很清楚,它能解决你的问题:)
我正在尝试更好地理解 ramda.js 中的功能组合,目前 class 中有一个方法如下所示:
const replace = (newItem) => function3(function1(newItem).function2(newItem));
我在 ramda.js 中知道一个更简单的函数,例如
const replace = (newItem) => function2(function1(newItem));
你可以这样写
const replace = compose(function2, function1);
是否有类似的方法可以使用函数组合/应用程序或其他 ramda.js 辅助方法对初始函数执行相同的操作?
Ramda 有两个函数可以帮助解决这个问题。比较标准的是lift
。许多函数式语言都有这个概念。考虑它的一种方法是,它提升了一个对值进行操作的函数,以创建一个对这些值的 容器 进行操作的函数:
add(3, 5) //=> 8
lift(add)([3], [5]) //=> [8]
函数也可以看作是值的容器。 return 给定类型值的函数可以被视为该类型的容器。
因此我们可以让您的 function3
不是对值进行操作,而是对这些值的容器进行操作,然后将其提供给这些函数的输入。这是一个以数组作为容器的示例:
const function1 = newItem => `function1(${newItem})`
const function2 = newItem => `function2(${newItem})`
const function3 = (v1, v2) => `function3(${v1}, ${v2})`
const combine = R.lift(function3)(function1, function2)
console.log(combine('foo')) //=> "function3(function1(foo), function2(foo))"
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.js"></script>
不太标准的函数是converge
。这仅关注功能,而不关注任意容器。在这种情况下它的工作原理类似。该函数是一次性创建的,而不是 lift
的两次创建。这意味着初始函数需要包装在一个数组中:
const function1 = newItem => `function1(${newItem})`
const function2 = newItem => `function2(${newItem})`
const function3 = (v1, v2) => `function3(${v1}, ${v2})`
const combine = R.converge(function3, [function1, function2])
console.log(combine('bar')) //=> "function3(function1(bar), function2(bar))"
<script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.25.0/ramda.js"></script>
converge
仅适用于函数,但它可以与多元函数一起使用。 lift
仅适用于一元的。 converge
是一个特定于 Ramda 的函数。我没有在其他地方看到它。所以,如果 lift
适合你,我建议你选择它。
所以你的问题是怎么写
function1(input).function2(input)
以实用的方式。如果我是正确的,方法如下:
首先让我们创建一个函数method
,它会为我们提供绑定到该对象的对象的方法:
const method = R.curry((name, object) => R.bind(object[name], object))
使用这个函数,我们可以将表达式重写为
method('function2', function1(input))(input)
但我们想要更干净、更可重用的东西,对吧?所以让我们做一些重构
method('function2', function1(input))(input)
method('function2')(function1(input))(input)
R.pipe(function1, method('function2'))(input)(input) // or use R.compose
R.converge(R.call, [
R.pipe(function1, method('function2')),
R.identity
])(input)
现在我们可以像这样定义我们的函数combine
const combine = (fn, name) =>
R.converge(R.call, [
R.pipe(fn, method(name)),
R.identity
])
表达式变为
combine(function1, 'function2')(input)
我希望我的解释很清楚,它能解决你的问题:)