在 Haskell 中,为什么 GHCi cmd 行允许我更改变量的值,这在从文本文件加载时是不允许的



我可以在GHCi中执行以下操作,我知道这在Haskell中是不可能的:

Prelude> myPi = 3.14
Prelude> myPi = 4
Prelude> myPi
4

但是如果我把它放在一个文件中,它会给我一个错误

-- main.hs
myPi = 3.14
myPi = 4
Prelude> :l main.hs
main.hs:2:1: error:
Multiple declarations of ‘myPi’
Declared at: main.hs:1:1
main.hs:2:1

GHCi 做了什么来允许我"重新声明"变量。有没有办法阻止这种情况的发生?

下面是一个会话,它演示了 GHCi不会更改值,而是引入了一个具有相同名称的新变量:

Prelude> let myPi = 3.14
Prelude> let f x = x + myPi
Prelude> let myPi = 4
Prelude> f 0
3.14

我可以在 GHCi 中执行以下操作,我知道这在 Haskell 中是不可能的

Prelude> myPi = 3.14
Prelude> myPi = 4
Prelude> myPi

ghci中,您基本上是在"隐式"do中工作。解释器将向其添加隐式let

因此,您写了相当于:

main = do
let myPi = 3.14
let myPi = 4
print myPi

如果我们对do符号进行脱糖,我们因此得到:

main = let myPi = 3.14 in (let myPi = 4 in print myPi)

我们在这里所做的是构造两个不同的变量,它们恰好具有相同的名称。let定义了一个作用域,因此在您的print myPi中,它采用作用域最接近的变量,即第二个变量。

但在内let … in …之外,还有一个值3.14myPi变量。所以你没有改变myPi的值.

如果我们例如写:

main = do
let myPi = 3.14
let myPi = 4 in print myPi
print myPi

它将首先打印4(从内myPi(,然后3.14(从外myPi(。

最新更新