我有一个 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 行之间切换以查看我上面描述的问题
最佳答案
这至少有两个问题。首先,您混淆了 compose
和 pipe
。它们非常相似,但它们以相反的顺序应用它们的功能。
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'))
但第二个问题更为根本。 pipe
和 compose
不会将其函数列表中的一项传递给另一项。相反,它们返回函数,其中第一个函数是针对提供的数据调用的,第二个是针对第一个的结果调用的,第三个是针对第二个的结果调用的,第四个是针对第三个的结果的,等等.
但是 filter
需要两个参数,一个谓词函数和一个值列表。
你的 filter(propEq('suit', 'CLUBS'))
正在传递 filter(propEq('suit', 'CLUBS'))
,一个函数一个参数由于 currying,到 filter
,它需要一个单参数函数和一个值列表。因为我们只传递第一个,所以我们返回一个函数,该函数获取值列表并将其过滤为匹配的值。
当你尝试说 pipe(propEq('suit', 'CLUBS'), filter)
,并使用名为 cards
的列表调用结果函数时,你将 cards
传递给 propEq('suit', 'CARDS')
,因为 cards
是一个没有 suit
的列表> 属性,它返回 false。然后使用此 false
值调用 filter
。因为这个柯里化(Currying)函数需要两个参数,所以你会得到一个寻找第二个参数的函数。不过,这是一个无用的函数,因为第一个参数 false
不是谓词函数。
我希望这是有道理的。昨晚我没睡多少觉,我不太确定什么是明智的。 :-)
关于javascript - 为什么我的 Ramda 管道功能不能与过滤器一起使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43591635/