Haskell 在筛选中考虑列表的其余部分

Haskell 在筛选中考虑列表的其余部分,haskell,filter,Haskell,Filter,我需要在列表中显示其后继元素较大的元素数。例如,在列表[3,7,2,1,9]中,我的函数应该返回2,因为7大于3,9大于1。 为了做到这一点,我考虑使用过滤功能: greaterElems :: Ord a => [a] -> Int greaterElems [] = 0 greaterElems [x] = 0 greaterElems (x:xs) = length (filter (< head xs) (x:xs)) greaterElems::Ord a=>[a]

我需要在列表中显示其后继元素较大的元素数。例如,在列表[3,7,2,1,9]中,我的函数应该返回2,因为7大于3,9大于1。
为了做到这一点,我考虑使用过滤功能:

greaterElems :: Ord a => [a] -> Int
greaterElems [] = 0
greaterElems [x] = 0
greaterElems (x:xs) = length (filter (< head xs) (x:xs))
greaterElems::Ord a=>[a]->Int
greaterElems[]=0
更大的元素[x]=0
greaterElems(x:xs)=长度(过滤器(
然而,这并没有像预期的那样起作用:Haskell似乎总是考虑列表中的第二个元素,好像“head xs”只计算了一次,但这在我看来并不正常,因为Haskell很懒。
我遗漏了什么?如何修复代码以实现我的目标?

您可以利用我们传递列表的位置及其尾部。事实上:

sucGreater :: Ord a => [a] -> [Bool]
sucGreater x = zipWith (<) x (tail x)
对于给定的样本列表,这为我们提供了:

Prelude> sucGreater [3,7,2,1,9]
[True,False,False,True]

我把它作为一个练习留给计算列表中
True
s的数量。

提示:使用
zipWith
但是,这并不像预期的那样有效:Haskell似乎总是考虑列表的第二个元素,好像“head xs”只计算一次,但这在我看来并不正常,因为Haskell很懒。
我不确定为什么您希望
头xs
被多次计算,或者为什么它会引用列表中第二个元素以外的任何元素。这与懒惰无关。这里通常使用的关于
tail
:最好使用
drop 1
,以防函数传递一个空列表。@RobinZigmond:在这里这无关紧要,因为
zipWith
将首先计算第一个参数。因此,即使你传递了一个空的列表,它也会工作,这是因为懒惰。但这很愚蠢——有一个微妙的错误,但是它被微妙的条件严格性所抵消。或者,您可以选择将所有依赖项都设置为0,而不是2,这取决于微妙的事情。。。
Prelude> sucGreater [3,7,2,1,9]
[True,False,False,True]