Suppose you have a variable with the following list:
Prelude> arr = [1,2,3,4,5]
And you do,
Prelude> arr
[1,2,3,4,5]
Prelude> arr = tail arr
Prelude> arr
Why does the compiler freeze up now? I am trying to implement this code statement in a recursion, but this phenomenon is preventing my recursion from working properly – it keeps returning an empty list error.
In Haskell, a variable is always in scope in its own definition. What you probably intended was this
Prelude> arr1 = [1,2,3,4,5]
Prelude> arr1
[1,2,3,4,5]
Prelude> arr2 = tail arr1
Prelude> arr2
[2, 3, 4, 5]
But when you write arr = tail arr
, the REPL forgets the previous definition of arr
and defines a new one which is equal to its own tail. Then you do
Prelude> arr
Haskell comes along and evaluates that to tail arr
, and tail
evaluates its argument to WHNF, so to identify tail arr
, we need to know the shape of arr
, which is, of course, tail arr
. So to know arr
, we need to know arr
. Hence, arr
is bottom, a nonterminating value. The previous definition is irrelevant.
If you had tried to do this in a Haskell source file (as opposed to the command line interactive environment), you'd get a compiler error, as it's incorrect to rebind an existing name in the same scope. It's only a feature of the REPL that you're allowed to do so for testing purposes.