***异常:Prelude.head:Haskell中的空列表

时间:2014-02-23 09:11:09

标签: haskell

我正在尝试编写一个执行此操作的函数: 函数[3,3,5,7] 1 = [(3,2),(5,1),(7,1)] 它在列表中生成唯一元素的元组,并给出元素的出现。我写了这个:

func [] n = []
func (x:xs) n = if x == head xs then func (xs) (n + 1) else (x, n) : func (xs) 1

我得到了这个例外:

  

* 异常:Prelude.head:空列表

为了解决这个问题,我写了这个:

func [] n = []
func [x] n = (x,n)
func (x:xs) n = if x == head xs then func (xs) (n + 1) else (x, n) : func (xs) 1

但现在我收到了这个错误:

  

无法匹配预期类型[a0]' with actual type(t0,t1)'   表达式:(x,n)在func的等式中:func [x] n =(x,n)

我该如何解决这个问题?

2 个答案:

答案 0 :(得分:9)

第一个问题在这里:

func (x:xs) n = if x == head xs ...

xs可以是空列表。你需要确保xs在结束之前不是空的。

第二个问题在这里:

func [] n = []
func [x] n = (x,n)

在第一行中,您说func的返回类型是一个列表,但在第二行中,您说它是一个元组 - 因此类型错误。

你想要的是非常接近group中的Data.List函数 - 这可以为你提供一些关于如何编写它的想法。

或者,这是一些指导。

显然:

func [] = []

对于递归案例,请尝试:

func (x:xs) = (x, n) : func rest
  where (n,rest) = ... (some function of x and xs) ...

也就是说,编写另一个函数来返回func必须处理的列表的计数和剩余部分。

答案 1 :(得分:3)

你的问题是在第二种情况下,你返回一个元组而不是一个列表。将该元组包装在列表中可以解决您的类型错误。

func :: Eq a => [a] -> Integer -> [(a, Integer)]
func []           _ = []
func [x]          n = [(x,n)]
func (x:xs@(y:_)) n = if x == y
                      then func xs (n + 1)
                      else (x,n) : func xs 1