当我尝试运行以下函数时,出现错误:
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]] - > [α]
有人可以解释一下,如何解决这个问题?这个错误究竟传达了什么?
答案 0 :(得分:3)
该行
listlon [] = 0
生成输出0
以代替[a]
类型的内容。你很可能意味着listlon [] = []
。不过我建议listlon = map length
或listlon = 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
的无点定义。
错误说编译器对返回类型感到困惑。您正尝试按文字Num
和0
以及列表形式(由最后一行构建)返回1
。约束Num [a]
只能使用扩展名FlexibleContexts
。但实际上它只表明我上面描述的问题。这些类型的错误消息有时会让人感到困惑,因为编译器无法读懂您的想法,因此它会假设您知道自己在做什么,并且只有在由于某些冲突而无法再继续推断类型时才报告问题。