在 haskell 中,GHCi 命令行上的 let x= 和 x= 之间有什么区别吗?



我正在用Haskell GHCi编写一个简单的声明

myPi = 3.14

我也可以把它写成

let myPi = 3.14

这两个声明之间这个非常简单的示例有什么区别吗?我知道let的额外功能,但这里不需要它

有一点区别,是的。在正常操作下,ghci 一次接受一行输入并立即处理。但是,它还具有"自动多行"模式,在该模式下,它将尝试检测您是否要一次输入多行,然后再将所有行一起处理。例如,在正常模式下:

> (3 +
<interactive>:1:5: error:
parse error (possibly incorrect indentation or mismatched brackets)
>  case () of
<interactive>:2:1: error:
Empty list of alternatives in case expression
Use EmptyCase to allow this

使用:set +m启用自动多行模式后(将其放在~/.ghci中以默认启用它!

> (3 +
| 4)
7
> case () of
|  () -> ()
|
()

有了这个序言,我现在可以告诉你小区别是什么:myPi = 3.14不会触发多行处理,而是立即定义它;但let myPi = 3.14确实触发了多行处理。例如,如果要创建相互递归绑定,这可能很重要;如果没有let,它们必须在一行中输入并用明确的分号分隔,而在let和自动多行模式下,您可以使用缩进以标准的惯用方式分隔它们。

(此外,如果您使用的是非常旧版本的 GHC,则非let形式可能尚不可用。

在 GHCi 提示符下,不,没有区别。

过去需要let(理由是 GHCi 提示有点像您在IOdo 块中输入行(。但相对较近的1它进行了更新,以便let是可选的,以提供更方便的交互式语法。


1在 GHC 8.0 中("添加了对顶级函数声明的支持"部分(。这已经足够旧了,你不太可能使用需要let的旧GHCi,但在此之前仍然有很多教程和其他材料(它们并不总是清楚地告诉你他们的示例中使用了什么版本(。对于某些人来说,旧习惯很难改变。

最新更新