Haskell rare pattern matching
The @"Hello"
is irrelevant here, all it does is fix the type to String
. You get the same behaviour with
s :: String
s = s
Which is semantically equivalent to
s' :: String
s' = undefined
which gives the result
Prelude> s'
"*** Exception: Prelude.undefined
What I mean by “semantically equivalent” is, both s
and s'
are examples of bottom values, i.e. values from that “sin bin of error values any type contains, thanks to non-strictness”. As soon as you hit a bottom value, the pure Haskell language is basically powerless and has give in to, well, undefined, “impure behaviour”, like letting you wait forever or throwing an exception.
However, again thanks to non-strictness, this needs not necessarily happen. When printing a value, the first thing that happens is, the Show
instance is invoked and asked to produce a string. A Haskell string is a lazy list. And the show
of any string begins with "
, therefore even if the string itself is utterly undefined, show
will manage to produce that one character.
We can observe this more sheltered with
Prelude> head $ show s
'"'
In let
s and top level expressions everything on the left-hand side of the =
is in scope on the right-hand side. So you've created a looping "bottom" value.
Notice this behaves the same way:
Prelude> let s = (s::String)
Prelude> s
"
That's because (simplifying) print
on String
is defined something equivalent to:
printString chars = putChar '"' >> mapM_ putChar chars
Because chars
is a loop the mapM_ putChar chars
appears to hang.