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

oro*_*ome 2 haskell types casting ihaskell

如果我定义

data Thing = Shoe
           | Ship
           | SealingWax
           | Cabbage
           | King
Run Code Online (Sandbox Code Playgroud)

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

thing :: Thing
thing = 4
Run Code Online (Sandbox Code Playgroud)

我得到一个错误("没有(Num Thing)的实例来自字面'4'")如预期的那样.但是,如果我第一次完成有效的绑定

thing :: Thing
thing = King
Run Code Online (Sandbox Code Playgroud)

然后,在一个单独的单元格中进行相同(无效)的赋值

thing = 4
Run Code Online (Sandbox Code Playgroud)

我没有得到任何错误和t: thing收益thing :: (Num a) => a.

更令人困惑的是,如果我放

thing = Cabbage
:t thing
thing = 5
:t thing
Run Code Online (Sandbox Code Playgroud)

在单个单元格中,我没有错误

thing :: Thing
thing :: (Num a) => a
Run Code Online (Sandbox Code Playgroud)

但没有:t线条的单个细胞

thing = Cabbage
thing = 5
Run Code Online (Sandbox Code Playgroud)

给出错误:

Multiple declarations of ‘thing’
Declared at: :1:1
             :2:1
Run Code Online (Sandbox Code Playgroud)

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

Tik*_*vis 5

在Haskell中,您无法更改或重新分配变量.你正在做的是声明一个只重用名称变量,但完全不同. shoe

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

单细胞的例子有点混乱:基本上,:t将细胞分成多个定义.有了:t它,好像你有两个细胞; 没有它,就好像你同时试图x用两种不同的方式来定义- 即使它们具有相同的类型也不会有效.

一般来说,Haskell中的阴影名称有点尴尬而且风格不好.您甚至可以启用它的警告:

:set -fwarn-name-shadowing
Run Code Online (Sandbox Code Playgroud)

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

:set -Wall
Run Code Online (Sandbox Code Playgroud)