为什么我可以在单独的 IHaskell Notebook 单元格中更改变量的类型?

Why can I change the type of a variable in separate IHaskell Notebook cells?

如果我定义

data Thing = Shoe
           | Ship
           | SealingWax
           | Cabbage
           | King

然后在 IHaskell Notebook 的后面的单元格中输入

thing :: Thing
thing = 4

我收到了预期的错误 ("No instance for (Num Thing) arising from the literal ‘4’")。但是如果我先用

完成一个有效的绑定
thing :: Thing
thing = King

然后,在一个单独的单元格中使用

进行相同的(无效的)赋值
thing = 4

我没有收到任何错误,t: thing 生成 thing :: (Num a) => a

更令人费解的是,如果我把

thing = Cabbage
:t thing
thing = 5
:t thing

在单个单元格中我没有收到任何错误并且

thing :: Thing
thing :: (Num a) => a

但没有 :t 行的单个单元格

thing = Cabbage
thing = 5

报错:

Multiple declarations of ‘thing’
Declared at: :1:1
             :2:1

为什么我可以在单独的 IHaskell Notebook 单元格中更改变量的类型?

在 Haskell 中,您不能 更改或重新分配变量。您正在做的是声明一个 new 变量,该变量仅重用 name shoe,但在其他方面完全不同。

您对 show shadows 的第二个定义是第一个,因为它采用相同的名称,但不会以任何其他方式影响它。

单单元格示例有点令人困惑:本质上,:t 将单元格分隔为多个定义。使用 :t,就好像您有两个单元格;没有它,就好像您同时尝试以两种不同的方式定义 x——即使它们具有相同的类型也不会起作用。

一般来说,在 Haskell 中隐藏名字有点尴尬,也不是好的风格。您甚至可以启用有关它的警告:

:set -fwarn-name-shadowing

它也可以作为更大的警告套件的一部分打开:

:set -Wall