为什么我的Ramda管道功能不能用于过滤器?

时间:2017-04-24 15:05:26

标签: javascript filter functional-programming pipe ramda.js

我有一个curried函数,我在一个合成中使用它,这有效:

const getClubs = R.filter(R.propEq('suit', 'CLUBS'))

这是一系列卡片对象并按照他们的诉讼过滤它们。

但是当我尝试取消此函数调用并将其转换为管道时:

const getClubs = R.pipe(R.filter, R.propEq('suit', 'CLUBS'))

...这不再适用,我甚至没有任何错误。我的管道或过滤器功能有什么问题?

这是working version of my code

在第8行和第9行之间切换以查看我上面描述的问题

1 个答案:

答案 0 :(得分:4)

这至少有两个问题。首先,您要混淆composepipe。它们非常相似,但它们以相反的顺序应用它们的功能。

pipe(g, f)(x);    //=> f(g(x))

compose(g, f)(x); //=> g(f(x))

因此,如果您想要等效filter(propEq('suit', 'CLUBS')),那么您需要编写以下内容而不是R.pipe(R.filter, R.propEq('suit', 'CLUBS'))

R.pipe(R.propEq('suit', 'CLUBS'), R.filter)
// or
R.compose(R.filter, R.propEq('suit', 'CLUBS'))

但第二个问题更为根本。 pipecompose不会将其功能列表中的一项传递给另一项。相反,它们返回的函数是针对提供的数据调用第一个函数,第二个函数针对第一个函数调用,第三个函数针对第二个函数调用,第四个函数针对第三个函数调用,等等

但是filter需要两个参数,一个谓词函数和一个值列表。

你的filter(propEq('suit', 'CLUBS'))正在将filter(propEq('suit', 'CLUBS'))(一个由于currying的参数的函数)传递给filter,它需要一个参数函数和一个值列表。因为我们只传递了第一个,所以我们得到一个函数,它接受值列表并将其过滤到匹配的值。

当您尝试时,说出pipe(propEq('suit', 'CLUBS'), filter),并使用名为cards的列表调用结果函数,您将cards传递给propEq('suit', 'CARDS'),并从cards开始是没有suit属性的列表,它返回false。然后,您使用此filter值调用false。由于此curried函数需要两个参数,因此您将返回查找第二个参数的函数。但是,这是一个无用的函数,因为第一个参数false不是谓词函数。

我希望这是有道理的。昨晚我没有多少睡眠,我不太清楚什么是明智的。 : - )