Haskell“where”缩进:为什么它必须缩进标识符? [英] Haskell "where" indentation: why must it be indented past identifier?

查看:162
本文介绍了Haskell“where”缩进:为什么它必须缩进标识符?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这段代码:

  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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆