在javascript中使用相同的参数组合链接函数

在javascript中使用相同的参数组合链接函数,javascript,functional-programming,ramda.js,Javascript,Functional Programming,Ramda.js,我试图更好地理解ramda.js中的函数组合,目前在一个类中有一个如下所示的方法: const replace = (newItem) => function3(function1(newItem).function2(newItem)); 我知道在ramda.js中有一个更简单的函数,比如 const replace = (newItem) => function2(function1(newItem)); 你可以这样写 const replace = compose(func

我试图更好地理解ramda.js中的函数组合,目前在一个类中有一个如下所示的方法:

const replace = (newItem) => function3(function1(newItem).function2(newItem));
我知道在ramda.js中有一个更简单的函数,比如

const replace = (newItem) => function2(function1(newItem));
你可以这样写

const replace = compose(function2, function1);

使用functional composition/application或其他ramda.js helper方法对初始函数也有类似的方法吗?

ramda有两个函数可以帮助实现这一点。更标准的是。许多函数式语言都有这个概念。考虑它的一种方式是,它提升了一个对值进行操作的函数,以创建一个对这些值的容器进行操作的函数:

add(3, 5) //=> 8
lift(add)([3], [5]) //=> [8]
函数也可以看作是值的容器。返回给定类型值的函数可以视为该类型的容器

因此,我们可以提升您的
function3
,使其不是对值进行操作,而是对这些值的容器进行操作,然后向其提供这些函数的输入。下面是一个将数组作为容器的示例:

const function1=newItem=>`function1(${newItem})`
const function2=newItem=>`function2(${newItem})`
常量function3=(v1,v2)=>`function3(${v1},${v2})`
恒联合收割机=右提升(功能3)(功能1、功能2)
console.log(combine('foo'))/=>function3(function1(foo),function2(foo))”

所以你的问题是如何写作

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)

我希望我的解释是清楚的,它解决了您的问题:)

复制
newItem
参数在无点样式下确实要困难得多。不要尝试。@Bergi是对的,如果有人想尝试,不要<代码>R.compose(function3、R.converge(R.call、[R.compose(R.flip)(R.invoker(1,'function2'))、function1、R.identity))从维护的角度来看是不可接受的。它还增加了函数调用的数量,这是一个荒谬的数目。谢谢-这看起来很接近,但我正在寻找的函数链脱离了第一个函数的结果。您的解决方案是
function3(function1(bar)、function2(bar))
,但我正在寻找
function3(function1(bar)、function2(bar))
(注意点)在发布此问题之前,我正在查看converge,但不太确定如何操作。我确实相信使用R.invoke和升力、收敛或合成的一些变体是可能的,但我不能完全理解。啊,是的,我确实读错了。Ramda在方法方面没有提供太多帮助,而是专注于函数。根据提供的另一个答案,这实际上是可能的,但是理解它的复杂性使得非点自由风格更加合理,因此我可能会坚持这一工作,方法可以替换为ramda的invoker函数,该函数基本上做相同的事情。e、 g.
R.converge(R.call,[R.compose(R.flip)(R.invoker(1,'function2')),function1,R.identity))
所以我的问题的解决方案是
R.compose(function3,R.converge(R.call,[R.compose](R.flip(R.invoker(1,'function2')),function1),R.identity))
~谢谢!作为旁注,它可能不值得使用,因为它很难阅读/理解,所以我可能只使用非点自由版本。