例外:Prelude.head:Haskell中的空列表



我正在尝试编写一个函数来执行此操作:func [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) 在函数的方程中: 函数 [x] n = (x, n)

我该如何解决这个问题?

第一个问题在这里:

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

xs可以是空列表。在取其头部之前,您需要确保xs不是空的。

第二个问题在这里:

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

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

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

或者,这里有一些指导。

清楚:

func [] = []

对于递归情况,请尝试以下操作:

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

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

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

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

最新更新