我有一个curried函数,我在一个合成中使用它,这有效:
const getClubs = R.filter(R.propEq('suit', 'CLUBS'))
这是一系列卡片对象并按照他们的诉讼过滤它们。
但是当我尝试取消此函数调用并将其转换为管道时:
const getClubs = R.pipe(R.filter, R.propEq('suit', 'CLUBS'))
...这不再适用,我甚至没有任何错误。我的管道或过滤器功能有什么问题?
在第8行和第9行之间切换以查看我上面描述的问题
答案 0 :(得分:4)
这至少有两个问题。首先,您要混淆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。然后,您使用此filter
值调用false
。由于此curried函数需要两个参数,因此您将返回查找第二个参数的函数。但是,这是一个无用的函数,因为第一个参数false
不是谓词函数。
我希望这是有道理的。昨晚我没有多少睡眠,我不太清楚什么是明智的。 : - )