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
showshadows 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
:tseparates 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 definexin 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:
It can also be turned on as part of a larger suite of warnings: