[Haskell-cafe] problem with IO, strictness, and "let"

Felipe Almeida Lessa felipe.lessa at gmail.com
Fri Jul 13 20:19:58 EDT 2007

On 7/13/07, Stefan O'Rear <stefanor at cox.net> wrote:
> 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}
[Arity 2
  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
[Arity 2
  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.



More information about the Haskell-Cafe mailing list