Haskell - 语法错误

时间:2017-10-06 20:18:30

标签: haskell syntax

有人可以告诉我这里有什么问题吗?我无法弄清楚错误的位置。我是haskell的新手,所以我不知道每个语法规则atm。

parseS (s:xs) | all isDigit s = (xs, Lit (read s)) 
          | s == " " = parseS xs
          | s == "-" = let (remainder, e) = parseS xs in (remainder, Sub e)
          | s == "+" = (xs'', Sum e e') where
                       (xs', e) = parseS xs 
                       (xs'', e') = parseS xs' 

          | s == "*" = (xs'', Mul e e') where     <- parse error on input on this line
                       (xs', e) = parseS xs 
                       (xs'', e') = parseS xs'  

2 个答案:

答案 0 :(得分:3)

问题是第一个where子句被视为parseS (s:xs)定义的结尾。您之后尝试添加另一个受保护的案例,但解析器并未将其视为附加到相同的定义。

有几种方法可以解决这个问题。

可以使用let ... in代替s == "+"

来解决此问题
      | s == "+" = let (xs', e) = parseS xs
                       (xs'', e') = parseS xs
                   in (xs'', Sum e e')
      | s == "*" = (xs'', Mul e e') where
                       (xs', e) = parseS xs 
                       (xs'', e') = parseS xs'  

但是有一种更简单的方法 - 只需删除where子句。

      | s == "+" = (xs'', Sum e e')
      | s == "*" = (xs'', Mul e e') where
                       (xs', e) = parseS xs 
                       (xs'', e') = parseS xs'  

where子句中定义的变量适用于整个定义(适用于所有保护案例),因此xs''的定义可以在两种情况下重复使用。

答案 1 :(得分:2)

这就是Haskell看到你的代码的方式:

parseS (s:xs)
        | all isDigit s = (xs, Lit (read s)) 
        | s == " " = parseS xs
        | s == "-" = let (remainder, e) = parseS xs in (remainder, Sub e)
        | s == "+" = (xs'', Sum e e')
    where
    (xs', e) = parseS xs 
    (xs'', e') = parseS xs' 

| s == "*" = (xs'', Mul e e')
    where
    (xs', e) = parseS xs 
    (xs'', e') = parseS xs'

where块附加到声明,在您的情况下是整个parseS定义。

|开头的下一行被视为新声明的开头,由于您无法使用|启动声明,因此该声明无效。

最简单的解决方法是停止使用where进行本地绑定,并使用let代替,如下所示:

          | s == "+" =
              let
                  (xs', e) = parseS xs 
                  (xs'', e') = parseS xs' 
              in
              (xs'', Sum e e')

          | s == "*" =
              let
                  (xs', e) = parseS xs 
                  (xs'', e') = parseS xs'
              in
              (xs'', Mul e e')