这是一项作业,它是删除相邻的重复项。
结果应该像这样removeAdjacentDuplicates [3,1,2,2,2,2,2,4,4,2,2,3] == [3,1,2,4,2,3]
我知道这里没有必要使用head
,但是不允许使用形式[e | e]的rekursion和List-Comprehensions。 ...]。仅Prelude中的功能是允许的group
等,在其他软件包中也不允许。推荐使用map zip filter concat reverse foldr
。
例如,不可能做到这一点:
removeAdjacentDuplicates :: Eq a => [a] -> [a]
removeAdjacentDuplicates (x:xs@(y:_))
| x == y = x:tail (removeAdjacentDuplicates xs)
| otherwise = x:removeAdjacentDuplicates xs
所以我这样尝试
removeAdjacentDuplicates = foldr (\x result -> if ( x == (head result)) then result else (x : result)) []
但是当我对其进行测试时,它会抛出*** Exception: Prelude.head: empty list' here
我尝试在之前添加removeAdjacentDuplicates [] = []
,
但是错误就像这样
Equations for ‘removeAdjacentDuplicates’ have different numbers of arguments
H7-1.hs:24:1-32
H7-1.hs:25:1-105
|
24 | removeAdjacentDuplicates [] = []
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^...
我不知道问题出在哪里,如何解决?
答案 0 :(得分:6)
x == head result
为result
, []
死亡-并且在result
的第一次迭代中[]
肯定为foldr
,因此添加一个当输入列表不需要foldr
进行任何迭代时,一种特殊情况就是完全解决了错误的情况!
您可以尝试将result
插入列表,而不是尝试从x
列表中提取值;所以考虑使用条件
[x] == take 1 result
相反-它永远不会死。
答案 1 :(得分:2)
如@DanielWagner所述,head :: [a] -> a
将为空列表引发错误。我们可以使用take :: Int -> [a] -> [a]
或使用模式匹配
counts > 0
在给定列表为非空的情况下,此处removeAdjacentDuplicates :: (Foldable f, Eq a) => f a -> [a]
removeAdjacentDuplicates = foldr f []
where f x ys@(y:_) | x == y = ys
f x ys = (x:ys)
将匹配,ys@(y:_)
为列表的开头。因此,在这种情况下,我们检查y
是否成立,如果成立,我们返回x == y
。否则,我们返回ys
。