此代码:
import Data.Char (digitToInt)
myInt :: String -> Int
myInt [] = error "bad input: empty string"
myInt (x:xs)
| x == '-' = -1 * myInt xs
| otherwise = foldl convert 0 (x:xs)
where convert acc x
| x `elem` ['0'..'9'] = 10 * acc + digitToInt x
| otherwise = error ("bad input: not an int - " ++ [x])
失败:
前奏> :l safeListFs.hs
[1/1]编译Main(safeListFs.hs,解释)safeListFs.hs:9:8:解析错误(可能是错误的缩进)
失败,模块加载:无。
但是这个版本:
import Data.Char (digitToInt)
myInt :: String -> Int
myInt [] = error "bad input: empty string"
myInt (x:xs)
| x == '-' = -1 * myInt xs
| otherwise = foldl convert 0 (x:xs)
where convert acc x
| x `elem` ['0'..'9'] = 10 * acc + digitToInt x
| otherwise = error ("bad input: not an int - " ++ [x])
没问题:
前奏> :l safeListFs.hs
[1/1]编译Main(safeListFs.hs,解释)
好的,模块已加载:Main。
我无法弄清楚为什么这两个最后的缩进很重要。
答案 0 :(得分:30)
答案 1 :(得分:13)
嵌套上下文必须比封闭上下文(n> m)进一步缩进。如果没有,L失败,编译器应指出布局错误。
来自http://www.haskell.org/onlinereport/syntax-iso.html。
这也会失败:
import Data.Char (digitToInt)
myInt :: String -> Int
myInt [] = error "bad input: empty string"
myInt (x:xs)
| x == '-' = -1 * myInt xs
| otherwise = foldl convert 0 (x:xs)
where convert acc x
| x `elem` ['0'..'9'] = 10 * acc + digitToInt x
| otherwise = error ("bad input: not an int - " ++ [x])
呃,我不善于解释事情。在where
关键字之后有一个新的上下文,因为你可以在那里指定多个函数 - 记住你的程序以隐式module Main where
开头,所以我认为要求函数体缩进是合乎逻辑的,就像在模块级别一样(编译器期望列M和N上的另一个标识符,以及声明体进一步缩进)。
fun = ...
^ where fun' = ...
M ^
N
fun'' = ...
fun2 = ...
答案 2 :(得分:6)
因为你应该总是缩进函数定义。
(在您的情况下,where
中同一列开始的所有内容都被视为“同级”定义。)