输入'if'上的解析错误

时间:2015-08-07 03:14:57

标签: haskell indentation

我似乎无法弄清楚为什么这段代码不起作用:

sgetLine  =  do  x <- getChar
              if x == '\n' 
                 then do 
                  putChar x
                  return []
                 else do 
                  putChar '_'
                  xs <- sgetLine
                  return (x:xs) 

奇怪的是,代码在我这样做时有效

sgetLine  =  do { x <- getChar
            ; if  x == '\n' 
                then do 
                 putChar x
                 return []
                else do 
                 putChar '_'
                 xs <- sgetLine
                 return (x:xs)}

感谢您的帮助!

2 个答案:

答案 0 :(得分:4)

因为空格在Haskell中很重要。您需要遵循缩进规则或使用显式大括号和分号(如第二个代码块中所示)。以下是修复第一个块的两种方法(还有其他方法):

sgetLine  =  do  x <- getChar
                 if x == '\n' 
                   then do 
                     putChar x
                     return []
                   else do 
                     putChar '_'
                     xs <- sgetLine
                     return (x:xs)

-- I prefer this one. In any case, it's just a matter of style, so YMMV.
sgetLine  =  do  
  x <- getChar
  if x == '\n' 
    then do 
      putChar x
      return []
    else do 
      putChar '_'
      xs <- sgetLine
      return (x:xs)

do块中的行必须缩进相同的数量,并且还使用do缩进到行的右侧。这样,编译器可以确定do块的开始和结束位置,而无需编写显式括号。

另请参阅:Haskell “where” indentation: why must it be indented past identifier?问题是关于where而不是do,但一般原则是相同的,并且那里的答案都很好。

答案 1 :(得分:1)

我怀疑您设置了五个空格的制表符,这会使x <- getCharif x == '\n'行显示在屏幕上。但是,编译器使用八个空格的tabstops,因此if x == '\n'行看起来更加缩进编译器。

您应该使用空格进行对齐,保留标签以进行缩进。 (很多人建议只使用空格but I won't。)