Haskell 我的代码由于使用了保护而导致解析错误

Haskell 我的代码由于使用了保护而导致解析错误,haskell,syntax,pattern-guards,Haskell,Syntax,Pattern Guards,我有以下代码: parsexpr::[String]->(Ast[String]) parseExpr[]=错误“不正确” parsexpr(s:ss)|所有isDigit s=(高(读s),ss) |s==“-”=let(e,ss')=parsexpr-ss-in(mine,ss')) |s==“+”=(和e',ss'')其中 (e,ss')=parsexpr-ss (e',ss'')=parsexpr ss' |s==“*”=(多个),ss“”)其中 (e,ss')=parsexpr-ss

我有以下代码:

parsexpr::[String]->(Ast[String])
parseExpr[]=错误“不正确”
parsexpr(s:ss)|所有isDigit s=(高(读s),ss)
|s==“-”=let(e,ss')=parsexpr-ss-in(mine,ss'))
|s==“+”=(和e',ss'')其中
(e,ss')=parsexpr-ss
(e',ss'')=parsexpr ss'
|s==“*”=(多个),ss“”)其中
(e,ss')=parsexpr-ss
(e',ss'')=parsexpr ss'
当我试图运行它时,我得到一个错误,说“parse error on input'|'”。它所说的这一行是:

。。。
(e',ss'')=parsexpr ss'
->|s==“*”=(多个,多个)其中
(e,ss')=parsexpr-ss
...
我想我明白为什么。我想这是因为我上面有两条线没有守卫,而哈斯凯尔在下面突然出现另一个守卫时感到困惑。但在这些情况下,我如何才能添加额外的守卫


我曾尝试使用分号分隔新行,但我对Haskell非常陌生,因此不太了解它的语法。

没有必要使用大括号(当然可以)。但你确实需要小心缩进。这并不像一开始看起来那么难

话虽如此,在受保护的表达式中确实不能使用
where
。在这种情况下,必须使用
let
,如下所示:

parseExpr :: [String] -> (Ast,[String])
parseExpr [] = error "Incorrect"
parseExpr (s:ss) | all isDigit s = (Tall (read s),ss)
              | s == "-" = let (e,ss') = parseExpr ss in (Min e,ss')
              | s == "+" = let (e,ss') = parseExpr ss
                               (e',ss'') = parseExpr ss'
                           in (Sum e e',ss'')
              | s == "*" = let (e,ss') = parseExpr ss
                               (e',ss'') = parseExpr ss'
                           in (Mult e e',ss'')
但是,在这里的例子中,guard表达式非常简单,可以用模式匹配来替换。(建议利用这个机会。模式匹配是Haskell最好的朋友。)在这种情况下,您可以使用
where

parseExpr :: [String] -> (Ast,[String])
parseExpr [] = error "Incorrect"
parseExpr (s:ss) | all isDigit s = (Tall (read s),ss)
parseExpr ("-":ss) = (Min e,ss') where (e,ss') = parseExpr ss
parseExpr ("+":ss) = (Sum  e e',ss'') where (e, ss' ) = parseExpr ss
                                            (e',ss'') = parseExpr ss'

parseExpr ("*":ss) = (Mult e e',ss'') where (e, ss' ) = parseExpr ss
                                            (e',ss'') = parseExpr ss'

使用where for all guards我认为Thomas是对的。解析错误可能是因为在解析第一个
where
后,代码会认为您的函数结束了。即使忽略解析错误,在本例中使用单个
where
也会减少相当数量的重复代码。谢谢!我现在可以看到我需要这样做了了解更多关于模式匹配的信息。非常好的答案。