有几次我想遍历一个列表并挑选出具有某些属性的元素,这些属性也依赖于列表中的下一个元素。对于一个简单的示例,我有一些代码可以计算函数f
在指定的时间间隔内更改符号的次数[a,b]
。这在像 C 这样的命令式语言中是相当明显的:
for(double x=a; x<=b; x+=(b-a)/n){
s*f(x)>0 ? : printf("%e %e\n",x, f(x)), s=sgn(f(x));
}
在 Haskell 中,我的第一直觉是用它的尾部压缩列表,然后应用过滤器并提取元素fst
或其他。但这似乎笨拙且效率低下,所以我硬生生把它变成了一个折叠:
signChanges f a b n = tail $
foldl (\(x:xs) y -> if (f x*f y)<0 then y:x:xs else x:xs) [a] [a,a+(b-a)/n..b]
无论哪种方式,我都觉得有一种“正确”的方式来做到这一点(就像在 Haskell 中经常出现的那样),而且我不知道(或者只是没有意识到)它是什么。对于如何以更惯用或更优雅的方式表达这一点的任何帮助,以及关于如何找到“正确”做事方式的建议,将不胜感激。