我正在尝试编写一个执行此操作的函数: 函数[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)
我该如何解决这个问题?
答案 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