Haskell“where”缩进:为什么必须缩进标识符?

时间:2010-02-08 17:22:32

标签: haskell indentation

此代码:

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。

我无法弄清楚为什么这两个最后的缩进很重要。

3 个答案:

答案 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中同一列开始的所有内容都被视为“同级”定义。)