在 Haskell 为什么 GHCi 命令行允许我更改变量的值,这在从文本文件加载时是不允许的
In Haskell why does the GHCi cmd line allow me to change the value of a variable, which isn't allowed when loading from a text file
我可以在 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 做了什么让我可以 'redeclare' 变量。有没有办法阻止这种情况发生?
I can do the following in GHCi, which I understand shouldn't be possible in Haskell
Prelude> myPi = 3.14
Prelude> myPi = 4
Prelude> myPi
在 ghci
中,您基本上是在 "implicit" 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 …
之外,还有一个 myPi
变量,值为 3.14
。所以你没有改变myPi
的值。
如果我们写:
main = do
let myPi = 3.14
let myPi = 4 in print myPi
print myPi
它会先打印4
(从里面的myPi
)然后是3.14
(从外面的myPi
)。
这是一个演示 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
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 做了什么让我可以 'redeclare' 变量。有没有办法阻止这种情况发生?
I can do the following in GHCi, which I understand shouldn't be possible in Haskell
Prelude> myPi = 3.14 Prelude> myPi = 4 Prelude> myPi
在 ghci
中,您基本上是在 "implicit" 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 …
之外,还有一个 myPi
变量,值为 3.14
。所以你没有改变myPi
的值。
如果我们写:
main = do
let myPi = 3.14
let myPi = 4 in print myPi
print myPi
它会先打印4
(从里面的myPi
)然后是3.14
(从外面的myPi
)。
这是一个演示 GHCi 不会 更改值,而是引入一个具有相同名称的新变量的会话:
Prelude> let myPi = 3.14
Prelude> let f x = x + myPi
Prelude> let myPi = 4
Prelude> f 0
3.14