2017-10-06 30 views
2

有人可以告诉我这里有什么问题吗?我找不出错误在哪里。我对haskell很陌生,所以我不知道语法atm的每个规则。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  <- parse error on input on this line 
         (xs', e) = parseS xs 
         (xs'', e') = parseS xs' 
+2

请将此处的代码,错误,示例数据或文本输出以纯文本的形式发布,而不是可能难以阅读的图像,不能复制粘贴以帮助测试代码或在答案中使用,并且不利于那些使用屏幕阅读器的人。您可以编辑您的问题以在问题的正文中添加代码。使用'{}'按钮来格式化任何代码块,或使用四个空格缩进以获得相同的效果。我们无法将您的屏幕截图作为代码运行。 – tadman

+3

请逐字发布错误消息。 –

回答

2

这是哈斯克尔是如何看待你的代码:

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') 
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''定义可以为这两种情况下被重用。