
| > let { | > n :: GHC.Prim.Int# | > Str: DmdType | > n = GHC.Prim.*# 4 ww3 | > } in | > case GHC.Prim.<# n 0 of wild1 { | > | > Is this really a lazy let, or is there some magic going on | > that means it is actually done strictly as it's an Int#? | | Yes, this let will be done strictly. Indeed, any let which is sure to | be demanded (according to the Demand value of the Id) will turn into a | case in STG, and similarly for an expression in the argument position of | a strict function call. | | I believe the motivation was that this makes things much easier for the | simplifier, but Simon PJ will be able to elaborate I'm sure. Yes, that's right. A strict let, where the RHS is just a primop that can't fault, is left as a let rather than being expressed as a case, because it can be 'floated' easily to somewhere else, or inlined. A 'case' says "do this here and now" and is much less mobile. But when the type is unboxed, the let is indeed done eagerly. It's a slight hack really. We could have Rec NonRec Unboxed as three forms of binding, but currently the latter are combined into NonRec and distinguished by type. Simon