给定列表列表,返回列表长度的Listh(在另一个列表中)

时间:2017-03-31 15:43:40

标签: algorithm list haskell

当我尝试运行以下函数时,出现错误:

len' [] = 0
len' (_:xs) = 1 + len' xs

listlon [] = 0
listlon [[]] = 1
listlon (x:xs) = ((len' x):(listlon xs))
  

functions.hs:41:1:错误:      •约束中的非类型变量参数:Num [a]       (使用FlexibleContexts允许此操作)     •检查推断类型时         listlon :: forall a t。 (Num [a],Num a)=> [[t]] - > [α]

有人可以解释一下,如何解决这个问题?这个错误究竟传达了什么?

1 个答案:

答案 0 :(得分:3)

该行

listlon [] = 0

生成输出0以代替[a]类型的内容。你很可能意味着listlon [] = []。不过我建议listlon = map lengthlistlon = map len'。或许我只是不明白你真正想要的是什么。作为第一步,提供预期的签名总是有帮助的。你是在追求一个函数listlon :: [[a]] -> [Int]吗?

如果我的理解是正确的,最直接的解决方法是:

listlon [] = []
listlon [x] = [len' x]
listlon (x:xs) = len' x : listlon xs

这可以修复类型。但你可以注意到第二个方程是多余的,这就足够了

listlon [] = []
listlon (x:xs) = len' x : listlon xs

现在您可以注意到这实际上是将len'映射到列表上,因此map len'作为listlon的无点定义。

错误说编译器对返回类型感到困惑。您正尝试按文字Num0以及列表形式(由最后一行构建)返回1。约束Num [a]只能使用扩展名FlexibleContexts。但实际上它只表明我上面描述的问题。这些类型的错误消息有时会让人感到困惑,因为编译器无法读懂您的想法,因此它会假设您知道自己在做什么,并且只有在由于某些冲突而无法再继续推断类型时才报告问题。