Haskell“where”缩进:为什么它必须缩进标识符? [英] Haskell "where" indentation: why must it be indented past identifier?
问题描述
import Data.Char(digitToInt)
$ b $ myInt :: String - > Int
myInt [] =错误bad input:empty string
myInt(x:xs)
| x ==' - '= -1 * myInt xs
|否则= foldl转换为0(x:xs)
其中convert acc x
| x`elem` ['0'..'9'] = 10 * acc + digitToInt x
|否则=错误(输入错误:不是int - ++ [x])
失败:
Prelude> :l safeListFs.hs
[1的1]编译Main(safeListFs.hs,解释)
safeListFs.hs:9:8:解析错误(可能是不正确的缩进)
失败,模块加载:无。
但是这个版本:
import Data.Char(digitToInt)
myInt :: String - > Int
myInt [] =错误bad input:empty string
myInt(x:xs)
| x ==' - '= -1 * myInt xs
|否则= foldl转换为0(x:xs)
其中convert acc x
| x`elem` ['0'..'9'] = 10 * acc + digitToInt x
|否则=错误(输入错误:不是int - ++ [x])
:
Prelude> :l safeListFs.hs
[1的1]编译Main(safeListFs.hs,解释)
好了,加载模块:Main。
我无法弄清楚为什么最后两个缩进很重要。
基本上,Haskell记录了
其中
出现之后的第一个非空格字符的列(在这种情况下, convert
)的 c
,并将在该列开始的以下行视为其中
。 继续定义上一行的行(如 |
guards)必须缩进到第一个非空格字符(代码中的 c
)的右侧。
缩进到 c
左边的一行会在之外,其中
(例如,您的下一个顶级功能的开始)。
它是后面第一个字符的列,其中
这是至关重要的,即使它是在一个新的线上:
其中
转换acc x
| ...
anotherFunction x y
^
This code:
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])
Fails:
Prelude> :l safeListFs.hs
[1 of 1] Compiling Main ( safeListFs.hs, interpreted )
safeListFs.hs:9:8: parse error (possibly incorrect indentation)
Failed, modules loaded: none.
But this version:
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])
is ok:
Prelude> :l safeListFs.hs
[1 of 1] Compiling Main ( safeListFs.hs, interpreted )
Ok, modules loaded: Main.
I can't figure out why those two last indents matter.
Basically, Haskell notes the column where the first non-space character after where
appears (in this case, the c
of convert
) and treats following lines beginning in that column as new definitions inside the where
.
A line that continues the definition of the previous line (such as your |
guards) must be indented to the right of the first non-space character (c
in your code).
A line indented to the left of c
would be outside the where
(for example, the start of your next top-level function).
It's the column of the first character following where
that is crucial, even if it's on a new line:
where
convert acc x
| ...
anotherFunction x y
^
这篇关于Haskell“where”缩进:为什么它必须缩进标识符?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!