我写了这段代码:
addNums key num = add [] key num
where add res a:as b:bs
| a == [] = res
| otherwise = add res:(a+b) as bs
在第 3 行,解释器说:
parse error (possibly incorrect indentation)
无论是代码还是缩进,我都找不到错误。我为每个选项卡放置了四个空格。
注解:
即使这样也无法编译:
addNums key num = add [] key num
where add res a:as b:bs
| a == [] = res
| otherwise = add res:(a+b) as bs
第 2 行:
Parse error in pattern: add
最佳答案
Haskell 的主要缩进规则是,如果你想在另一行继续定义,它必须比你定义的内容进一步缩进。在这种情况下,您的add
的守卫函数的缩进较少,所以这就是编译器所提示的。
忽略代码中的其他错误,缩进应该是这样的:
addNums key num = add [] key num
where add res a:as b:bs
| a == [] = res
| otherwise = add res:(a+b) as bs
另请注意,缩进的确切数量无关紧要,只有连续行相对于所定义事物的缩进。
您的代码的另一个语法问题是您似乎误解了 Haskell 的优先规则。在 Haskell 中,函数应用程序的绑定(bind)比任何运算符都更紧密,所以
add res a:as b:bs
被解析为 (add res a):(as b):bs
, 而你的意思是 add res (a:as) (b:bs)
.最后的问题是类型错误。
(:)
运算符的类型为 a -> [a] -> [a]
,这意味着它需要一个元素和一个列表,并生成一个列表。在您的代码中 res:(a+b)
,您似乎有相反的情况,如 res
是一个列表和 a+b
是元素。由于 Haskell 中没有将单个元素附加到列表末尾的运算符,因此您必须使用列表连接运算符 (++) :: [a] -> [a] -> [a]
改为:res ++ [a+b]
.您还在比较元素
a
到列表[]
在你的保护下。这可能不是你的意思,模式 (a:as)
如果列表为空,则不匹配。最简单的解决方案是添加另一个模式而不是你的 guard 。把所有这些放在一起,这段代码应该能达到你的预期:
addNums key num = add [] key num
where add res [] _ = res
add res (a:as) (b:bs) = add (res ++ [a+b]) as bs
附言重复追加到列表的末尾不是很有效。事实上,它是 O(n2)。您可能希望添加到前面,并在完成后反转列表。这是 O(n)。
引用:
关于haskell - 为什么要解析错误?缩进?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7178199/