
On 7/13/07, Stefan O'Rear
instance Eval Int where ... seq (-1) b = b seq 0 b = b seq 1 b = b ...
I don't think you need all these cases. In fact, you can write instance Eval Int where seq 0 b = b seq _ b = b which, in GHC -O2, desugars to Main.$f1 :: {Main.Eval GHC.Base.Int} [GlobalId] [Arity 2 NoCafRefs Str: DmdType U(A)S] Main.$f1 = \ (@ b_adV) (ds_dxz :: GHC.Base.Int) (a_adi :: b_adV) -> case ds_dxz of wild_Xd { GHC.Base.I# ds1_dxA -> a_adi } As a matter of fact, the function seq' :: Int -> b -> b seq' n a = Prelude.seq n a desugars to Main.seq' :: forall b_ade. GHC.Base.Int -> b_ade -> b_ade [GlobalId] [Arity 2 NoCafRefs Str: DmdType U(A)S] Main.seq' = \ (@ b_adX) (n_adg :: GHC.Base.Int) (a_adh :: b_adX) -> case n_adg of tpl_Xf { GHC.Base.I# a1_sxX -> a_adh } which is the same as before. For those not familiar with GHC core, the above corresponds to seq :: Int -> b -> b seq n a = case n of I# _ -> a and the DmdType (created by the strictness analyser) tell us that the first argument is unboxed and absent ("U(A)"), so indeed its use is strict. It also tell us that the second argument is strict ("S"). Although we don't evaluate it to WHNF, we *always* return it (unless, of course, our Int is _|_), so it is needed to produce the result of the function regardless of the other argument. I'm also tempted to note that the second argument is indeed strict as seq n _|_ = _|_ for every n. HTH, -- Felipe.