If I define
data Thing = Shoe
| Ship
| SealingWax
| Cabbage
| King
and then in a later cell in an IHaskell Notebook enter
thing :: Thing
thing = 4
I get an error ("No instance for (Num Thing) arising from the literal ‘4’") as expected. But if I first complete a valid binding with
thing :: Thing
thing = King
and then later, in a separate cell make the same (invalid) assignment with
thing = 4
I get no error, and t: thing
yields thing :: (Num a) => a
.
More perplexingly, if I put
thing = Cabbage
:t thing
thing = 5
:t thing
in a single cell I get no errors and
thing :: Thing
thing :: (Num a) => a
but a single cell without the :t
lines
thing = Cabbage
thing = 5
gives an error:
Multiple declarations of ‘thing’
Declared at: :1:1
:2:1
Why can I change the type of a variable in separate IHaskell Notebook cells?
In Haskell, you can't change or reassign variables. What you're doing is declaring a new variable that just reuses the name shoe
, but is otherwise entirely distinct.
Your second definition of show
shadows the first because it takes the same name, but it doesn't affect it in any other way.
The single-cell example is a bit more confusing: essentially, a :t
separates the cell into multiple definitions. With the :t
, it's as if you had two cells; without it, it's as if you simultaneously tried to define x
in two different ways—which wouldn't have worked even if they had the same type.
In general, shadowing names in Haskell is a bit awkward and not good style. You can even enable a warning about it:
:set -fwarn-name-shadowing
It can also be turned on as part of a larger suite of warnings:
:set -Wall