I am experimenting with GHCi's :sprint
command. Consider the following:
GHCi> xs = [1..10] :: [Int]
GHCi> :sprint xs
xs = _
GHCi> length xs
10
GHCi> :sprint xs
xs = [1,2,3,4,5,6,7,8,9,10]
This works as expected. What interested me is :sprint
's behaviour after we interrupt some computation. Consider the following:
GHCi> xs = [1..] :: [Int]
GHCi> :sprint xs
xs = _
GHCi> length xs
Interrupted.
GHCi> :sprint xs
And it hangs.
The expected result was something like that (modulo the number of :
s):
xs = _ : _ : _ : _
What causes :sprint ...
to freeze? Why is there no access to information about the part of the list which was computed? It seems like a bug to me - there's no real reason to cast away all the work the interrupted length
did. Is it a bug indeed, or am I wrong?
As @Daniel Wagner explained in the comments, GHCi actually behaves exactly as you expect. It seems to hang because length
is extremely fast, and evaluates a huge number of elements, which takes :sprint
some time to pretty-print to a string. Unlike ordinary GHCi output, :sprint
forces it's string value before it starts printing. If you would wait long enough, :sprint
would indeed print the partial string as expected.
You can demonstrate this as follows:
GHCi> xs = [1..100000] :: [Int]
GHCi> :sprint xs
xs = _
GHCi> xs
[1,2,3,4 ... 8504^CInterrupted.
GHCi> :sprint xs
1 : 2 : 3 : 4 : ... : 8504 : _