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

In haskell is there any difference between a let x= and an x= on the GHCi command line?

我正在 Haskell GHCi

中写一个简单的声明
myPi = 3.14

我也可以这样写

let myPi = 3.14

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

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

let 曾经是必需的(原因是 GHCi 提示有点像您在 IO do 块中输入行)。但是最近1更新了let是可选的,以提供更方便的交互语法。


1GHC 8.0 中("Added support for top-level function declarations" 部分)。这已经足够老了,你不太可能使用需要 let 的旧 GHCi,但在那之前仍然有很多教程和其他 material(它们并不总是告诉你清楚地知道他们的示例中使用的是什么版本)。对于某些人来说,旧习难改。

有一点不同,是的。在正常操作下,ghci 一次接受一行输入并立即处理。然而,它也有一个 "automatic multiline" 模式,在这种模式下,它会尝试检测你是否想一次输入多行,然后再一起处理它们。例如,在普通模式下:

> (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 形式可能还不可用。)