如何在此处解决“ ***例外:Prelude.head:空列表”

时间:2019-06-16 01:36:53

标签: haskell

这是一项作业,它是删除相邻的重复项。 结果应该像这样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 [] = []
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^...

我不知道问题出在哪里,如何解决?

2 个答案:

答案 0 :(得分:6)

如果x == head resultresult

[]死亡-并且在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