Understanding the various thunks behavior when GHCi allows bindings

I played with examples from Simon Marlowe's book on parallel and parallel programming in Haskell and came across interesting behavior that I really don't understand. It really is that I am trying to understand some of the internal actions of the GHC.

Let's say I do the following in REPL:

λ» let x = 1 + 2 :: Int λ» let z = (x,x) λ» :sprint x x = _ λ» :sprint z z = (_,_) λ» seq x () () λ» :sprint z z = (3,3) 

Well, that is pretty much what I expected, except that z is already being evaluated by WHNF. Let me write a similar program and put it in a file:

 module Thunk where import Debug.Trace x :: Int x = trace "add" $ 1 + 2 z :: (Int,Int) z = (x,x) 

And play with him in GHCi:

 λ» :sprint x x = _ λ» :sprint z z = _ λ» seq x () add () λ» :sprint z z = _ λ» seq z () () λ» z (3,3) 

So this is a little different: z is not evaluated in advance by WHNF. My question is:

Why z is evaluated by WHNF in REPL when let z = (x,x) executed, but not when loading a definition from a file. My suspicion is that this has something to do with template binding, but I don’t know where to look for this for clarification (maybe I'm just completely completely wrong). I would expect it to somehow behave like an example in a file.

Any pointers or a brief explanation of why this is happening?

+42
haskell lazy-evaluation ghci thunk
Jul 15 '14 at 10:20
source share
1 answer

Since (,) is a constructor, the difference has nothing to do with the Haskell semantics ( :sprint provides access to the internal details of the thunk implementation, so it is not taken into account.) So this is a question of what GHC optimizations and trade-offs are when compiling (x,x) in different positions. Someone may know the exact cause in these cases.

+2
Mar 03 '15 at 7:18
source share



All Articles