Let me answer this question by showing how GHC actually does this, using the ghc-heap-view
library. You can probably reproduce this with ghc-vis
and get nice pictures.
I start by creating a data structure with an exception value somewhere:
Prelude> :script /home/jojo/.cabal/share/ghc-heap-view-0.5.1/ghci
Prelude> let x = map ((1::Int) `div`) [1,0]
At first it is purely a thunk (that seems to involve various type classes):
Prelude> :printHeap x
let f1 = _fun
in (_bco [] (_bco (D:Integral (D:Real (D:Num _fun _fun _fun _fun _fun _fun _fun) (D:Ord (D:Eq _fun _fun) _fun _fun _fun _fun _fun _fun _fun) _fun) (D:Enum _fun _fun f1 f1 _fun _fun _fun _fun) _fun _fun _fun _fun _fun _fun _fun) _fun) _fun)()
Now I evaluate the non-exception-throwing-parts:
Prelude> (head x, length x)
(1,2)
Prelude> System.Mem.performGC
Prelude> :printHeap x
[I# 1,_thunk (_fun (I# 1)) (I# 0)]
The second element of the list is still just a “normal” thunk. Now I evaluate this, get an exception, and look at it again:
Prelude> last x
*** Exception: divide by zero
Prelude> System.Mem.performGC
Prelude> :printHeap x
[I# 1,_thunk (SomeException (D:Exception _fun (D:Show _fun _fun _fun) _fun _fun) DivideByZero())]
You can see it is now a thunk that references an SomeException
object. The SomeException
data constructor has type forall e . Exception e => e -> SomeException
, so the second parameter of the constructor is the DivideByZero
constructor of the ArithException
exception, and the first parameter the corresponding Exception
type class instance.
This thunk can be passed around just like any other Haskell value and will, if evaluated, raise the exception again. And, just like any other value, the exception can be shared:
Prelude> let y = (last x, last x)
Prelude> y
(*** Exception: divide by zero
Prelude> snd y
*** Exception: divide by zero
Prelude> System.Mem.performGC
Prelude> :printHeap y
let x1 = SomeException (D:Exception _fun (D:Show _fun _fun _fun) _fun _fun) DivideByZero()
in (_thunk x1,_thunk x1)
The same things happen with threads and MVars, nothing special there.