Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Observing lazyness in Haskell

Is it possible to write a Haskell function which depends on whether values are calculated already or are thunks? E.g. if lazyShow :: [Int] -> String shows thunks as ? and calculated values normally, in GHCi we would see

> let nats = [0..]

> lazyShow nats
0 : ?

> nats !! 5    
5

> lazyShow nats
0 : 1 : 2 : 3 : 4 : ? 
like image 946
Alexey Romanov Avatar asked Nov 22 '13 08:11

Alexey Romanov


2 Answers

Clearly, lazyShow cannot have the type you state. If the string should depend on the current state of evaluation, then IO String as a result is the best you can hope for.

If all you're interested in is using this for debugging, then I think that the ghc-heap-view package (and potentially a graphical frontend such as ghc-vis) are useful for this purpose. It defines a GHCi command :printHeap that can be used to display a description of how the value looks in GHC's heap. It's perhaps a bit more low-level than what you intended, but it can be quite useful to understand better how lazy evaluation and sharing work:

Prelude> let nats = [0..]
Prelude> :printHeap nats
(_bco (D:Enum _fun _fun _fun _fun _fun _fun _fun _fun) _fun)()
Prelude> null nats
False
Prelude> System.Mem.performGC
Prelude> :printHeap nats
let x1 = S# 0
in x1 : _thunk x1 (S# 1)
Prelude> nats !! 5
5
Prelude> System.Mem.performGC
Prelude> :printHeap nats
let x1 = S# 5
in S# 0 : S# 1 : S# 2 : S# 3 : S# 4 : x1 : _thunk x1 (S# 1)

I'm explicitly calling the garbage collector via System.Mem.performGC (as recommended in the documentation of ghc-heap-view) to clean up the view a bit.

like image 76
kosmikus Avatar answered Oct 25 '22 14:10

kosmikus


You might be interested in digging the implementation of ":sprint" in GHCi, which has capability of looking into thunks:

> let a = map (+1) [1..10]
> :sprint a
a = _

> length a
10

> :sprint a
a = [_,_,_,_,_,_,_,_,_,_]

> take 5 a
[2,3,4,5,6]

> :sprint a
a = [2,3,4,5,6,_,_,_,_,_]
like image 32
oshyshko Avatar answered Oct 25 '22 13:10

oshyshko