Javascript 生成高阶函数的惯用Ramda?

Javascript 生成高阶函数的惯用Ramda?,javascript,functional-programming,higher-order-functions,currying,ramda.js,Javascript,Functional Programming,Higher Order Functions,Currying,Ramda.js,我的目标是创建一个自定义映射函数,在对每个项调用提供的函数之前,该函数首先需要过滤列表以保留(例如,仅保留偶数项)。我确实需要curry函数,并且第一个参数是函数,而不是列表。我相信签名应该是这样的:(a->b)->[a]->[b] 当然有很多方法可以做到这一点。这是我第一次尝试的样子 var isEven=x=>x%2==0; var filterEvensMap=R.curry((fn,items)=>R.map(fn,R.filter(isEven,items)); FilterEvent

我的目标是创建一个自定义映射函数,在对每个项调用提供的函数之前,该函数首先需要过滤列表以保留(例如,仅保留偶数项)。我确实需要curry函数,并且第一个参数是函数,而不是列表。我相信签名应该是这样的:
(a->b)->[a]->[b]

当然有很多方法可以做到这一点。这是我第一次尝试的样子

var isEven=x=>x%2==0;
var filterEvensMap=R.curry((fn,items)=>R.map(fn,R.filter(isEven,items));
FilterEventsMap(R.negate[1,2,3,4]);//[-2, -4]
然而,由于上面使用了带有
fn
items
“粘合参数”的匿名函数,我不确定这是否是Ramda打算使用的方式

下面我介绍了另一种方法。这似乎更符合拉姆达的精神,但我不确定我是否把事情复杂化了

var filterEventsMap=R(
R.flip,
R.uncurryN(2)
)(R(
R.flip(R.map),
R.过滤器(isEven)
));
我是否过度复杂化了多重组合和未修正?有没有更惯用的方法来实现这一点?根据你的经验,这有关系吗


提前感谢。

如果您发现Haskell签名很有用,您可能会发现此()也很有用。如果要简化表达式,可以输入与JS代码等效的Haskell:

filterEvensMap = \fn items -> map fn (filter isEven items)
它会给你一个无积分的等价物:

filterEvensMap = (. filter isEven) . map
然后使用Ramda将其翻译回JS:

var filterEvensMap = R.curry(R.compose(R.compose(R.filter(isEven)), R.map))
根据你的经验,这有关系吗


我将使用最具可读性的表达式,在本例中,它可能是原始表达式。无点签名很有趣,在某些地方可以增加清晰度,但它也会大大降低可读性,或者至少降低理解水平。

如果您发现Haskell签名很有用,您可能会发现此()也很有用。如果要简化表达式,可以输入与JS代码等效的Haskell:

filterEvensMap = \fn items -> map fn (filter isEven items)
它会给你一个无积分的等价物:

filterEvensMap = (. filter isEven) . map
然后使用Ramda将其翻译回JS:

var filterEvensMap = R.curry(R.compose(R.compose(R.filter(isEven)), R.map))
根据你的经验,这有关系吗


我将使用最具可读性的表达式,在本例中,它可能是原始表达式。Point free很有趣,在某些地方可以增加清晰度,但它也会大大降低可读性,或者至少降低理解水平。

嘿,谢谢你的提示,pointfree.js看起来非常有用。不过,OP中的预期行为与从无点Haskell表达式派生的Ramda表达式之间有一点不匹配:过滤需要在原始VAL上进行,而不是在映射的VAL上进行。下面是一个显示差异的链接:。我不太熟悉Haskell语法,所以我仍在努力找出问题所在。哦,我犯了一个错误,它应该是
compose(pipe(filter(f)),map)
,但由于某种原因,它在Ramda中不起作用。我的猜测是,自动咖喱和可变组合/管道把事情搞砸了,但你可以在这里看到它在香草JS中工作:再次感谢!我正在标记为已回答,因为我拥有继续编程所需的一切。我现在意识到,我在问题中所指的是一个叫做“无点”的概念,并不总是因为有可能就需要编写一个无点表达式。但是,当我想玩的时候,有一个pointfree.js刚刚提交了一个编辑,将您的示例Ramda代码包装在
R.curry
中(使用
R.compose
创建的函数默认情况下不使用curry)。原始版本也有一个轻微的重构,删除额外的
参数。谢谢你的提示,pointfree.js看起来非常有用。不过,OP中的预期行为与从无点Haskell表达式派生的Ramda表达式之间有一点不匹配:过滤需要在原始VAL上进行,而不是在映射的VAL上进行。下面是一个显示差异的链接:。我不太熟悉Haskell语法,所以我仍在努力找出问题所在。哦,我犯了一个错误,它应该是
compose(pipe(filter(f)),map)
,但由于某种原因,它在Ramda中不起作用。我的猜测是,自动咖喱和可变组合/管道把事情搞砸了,但你可以在这里看到它在香草JS中工作:再次感谢!我正在标记为已回答,因为我拥有继续编程所需的一切。我现在意识到,我在问题中所指的是一个叫做“无点”的概念,并不总是因为有可能就需要编写一个无点表达式。但是,当我想玩的时候,有一个pointfree.js刚刚提交了一个编辑,将您的示例Ramda代码包装在
R.curry
中(使用
R.compose
创建的函数默认情况下不使用curry)。原始版本也有一个轻微的重构,以删除额外的
参数。