haskell - 为什么要解析错误?缩进?

标签 haskell pattern-matching indentation parse-error

我写了这段代码:

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)。

引用:
  • Indentation
  • Pattern matching
  • 关于haskell - 为什么要解析错误?缩进?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7178199/

    相关文章:

    powershell - 在Powershell中用缩进和换行符替换字符

    visual-studio-2012 - 如何在 VS2012 中自动格式化代码缩进?

    python - 在 python 命令行中使用 'tab' 按钮缩进

    haskell - 如何在堆栈中使用 "-ddump-minimal-imports"

    haskell - 使用 ViewPatterns 和 PatternSynonyms 进行简单的模式匹配

    python - Python 中的多维/多变量动态时间规整 (DTW) 库/代码

    java - Mongodb查询匹配以空格分隔的单词

    python-3.x - 用opencv寻找手写箭头的特征

    haskell - vim-haskellmode 和 hsenv

    haskell - 我怎样才能对我的 GADT 进行脱糖?