Haskell:输入上的分析错误'|';

Haskell:输入上的分析错误'|';,haskell,guard,parse-error,Haskell,Guard,Parse Error,我有以下代码,用于从m提取一个双工,并用表达式e的求值替换以s开头的双工 exec (Assign s e) m = assign s (eval e m) m where assign _ _ [] = error ("undef var " ++ s) assign s v (x:xs) | fst x == s = if sameKind v (fst x) then (fst x,v):xs

我有以下代码,用于从
m
提取一个双工,并用表达式
e
的求值替换以
s
开头的双工

exec (Assign s e) m = assign s (eval e m) m
where assign _ _ [] = error ("undef var " ++ s)
    assign s v (x:xs)
        | fst x == s = if sameKind v (fst x)
                        then (fst x,v):xs
                        else error "type error in assign"
        | otherwise = x:(assign s v xs)
            where sameKind (VInt a) (VInt b) = True
                sameKind (VBool a) (VBool b) = True
                sameKind _ _ = False
编译时,我得到一个错误:
parse error on input'|'

有人知道如何解决这个问题吗?

根据:

制表位间距为8个字符

您的代码似乎是为5(?)个空格选项卡设计的;更改编辑器的选项卡设置或停止使用选项卡,问题就会消失

原因是:Haskell认为你是这样缩进的:

where assign _ _ [] = error ("undef var " ++ s)
        assign s v (x:xs)
如您所见,这意味着第二个定义的起点仍然在第一个定义的RHS内

此外:

不要这样做:

where f [] = one_expr
      f (x:xn) = another_expr

因为这会让你很难把
where
关键字和第一个等式分开,也因为这意味着你取决于Haskell认为
where
关键字和缩进的相对宽度,这就是你这次的感受。在Haskell中,制表符是可以使用的,只要您只依赖于给定行上的前导缩进并且是一致的,但这意味着您总是需要在
where
let
case
/
of
do
之后有一个换行符(并进一步缩进),可能还有其他我忘记的字符。(当然,当整个构造在一行上时,
do
let
除外)。

您似乎在用制表符缩进。使用空间,它有更高的工作机会。(如果要使用制表符,则必须将内容拆分到更多行。制表符也不利于对齐。)将制表符替换为空格,现在在第三行的输入“assign”上出现解析错误。因此,我想这将是一个新问题。您所有的
分配
都必须彼此对齐,就像
sameKind
一样。您的第一个
位置(在
exec
下)应该缩进更多。如果缩进了,则在复制和粘贴过程中一定发生了什么。不管怎样,我把它对齐了,效果很好。谢谢