简体   繁体   English

使用javascript中的相同参数撰写链接函数

[英]compose chained functions using the same parameter in javascript

I am trying to better understand functional composition in ramda.js and currently have a method in a class that looks like this: 我试图更好地理解ramda.js中的函数组成,并且目前在类中有一个方法,如下所示:

const replace = (newItem) => function3(function1(newItem).function2(newItem));

I know in ramda.js for a simpler function like 我在ramda.js中知道一个更简单的功能,例如

const replace = (newItem) => function2(function1(newItem));

you could write it like 你可以这样写

const replace = compose(function2, function1);

Is there a similar way to do the same with the initial function using functional composition / application or other ramda.js helper methods? 是否有使用功能组合/应用程序或其他ramda.js帮助程序方法对初始函数执行相同操作的类似方法?

Ramda has two functions that should help with this. Ramda有两个功能应该可以帮助您。 The more standard one is lift . 更标准的一种是lift Many functional languages have this concept. 许多功能语言都有这个概念。 One way to think about it is that it lifts a function which operates on values to create one that operates on containers of those values: 考虑它的一种方法是,它提升一个对值进行操作的函数,以创建对这些值的容器进行操作的函数:

add(3, 5) //=> 8
lift(add)([3], [5]) //=> [8]

Functions can be seen as containers of values too. 函数也可以看作是值的容器。 Functions which return values of a given type can be considered containers for that type. 返回给定类型的值的函数可以视为该类型的容器。

So we can lift your function3 to operate not on values, but on containers for those values, and then supply it the input to those functions. 因此,我们可以提升您的function3使其不对值进行操作,而是对这些值的容器进行操作,然后将其提供给这些函数。 Here's an example with arrays as containers: 这是一个将数组作为容器的示例:

 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> 


The less standard function is converge . 次标准函数converge This is focused only on functions, and not on arbitrary containers. 这仅专注于函数,而不专注于任意容器。 It works similarly in this case. 在这种情况下,它的工作原理类似。 The function is created in one pass rather than the two for lift . 该功能在一个传球,而不是两个用于产生lift And that means the initial functions need to be wrapped in an array: 这意味着初始函数需要包装在数组中:

 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 is only for functions, but it can work with polyadic functions. converge仅适用于函数,但可以与多元函数一起使用。 lift will work only with unary ones. lift只适用于一元 converge is a Ramda-specific function. converge是特定于Ramda的功能。 I haven't seen it elsewhere. 我没在其他地方看到过。 So, if lift will work for you, I would suggest you choose it instead. 因此,如果lift适合您,我建议您选择它。

So your question is how to write 所以你的问题是如何写

function1(input).function2(input)

In a functional way. 在功能上。 If I am correct, here is how: 如果我是正确的,这是怎么做的:

First let's create a function method that would give us a method of an object bound to that object: 首先让我们创建一个函数method ,该method将为我们提供绑定到该对象的对象的方法:

const method = R.curry((name, object) => R.bind(object[name], object))

Using this function, we can rewrite our expression as 使用此函数,我们可以将表达式重写为

method('function2', function1(input))(input)

But we want something cleaner and more re-usable, right? 但是我们想要更清洁,更可重用的东西,对吗? So let's do some refactoring 所以让我们做一些重构

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)

Now we can define our function combine like so 现在我们可以像这样定义函数combine

const combine = (fn, name) =>
  R.converge(R.call, [
    R.pipe(fn, method(name)),
    R.identity
  ])

And the expression becomes 表达式变成

combine(function1, 'function2')(input)

I hope my explanation is clear and it solves your problem :) 我希望我的解释很清楚,并且可以解决您的问题:)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM