我似乎无法弄清楚为什么这段代码不起作用:
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)}
感谢您的帮助!
答案 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 <- getChar
和if x == '\n'
行显示在屏幕上。但是,编译器使用八个空格的tabstops,因此if x == '\n'
行看起来更加缩进编译器。
您应该使用空格进行对齐,保留标签以进行缩进。 (很多人建议只使用空格but I won't。)