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