Demand analysis: `seq`'s strictness signature says its first argument is not head-used
seq
is one of the most primitive functions when it comes to demand analysis. It lowers to a case
in Core that puts a weak head demand on the its first argument.
Here's an example:
f = seq
which surprisingly simplifies to (in GHC 8.8.4, but similarly in current HEAD)
f :: forall a b. a -> b -> b
[GblId,
Arity=2,
Caf=NoCafRefs,
Str=<S,1*U><S,1*U>,
Unf=Unf{Src=InlineStable, TopLvl=True, Value=True, ConLike=True,
WorkFree=True, Expandable=True,
Guidance=ALWAYS_IF(arity=2,unsat_ok=True,boring_ok=True)
Tmpl= \ (@ a_11)
(@ b_12)
(v_B1 [Occ=Once] :: a_11)
(v1_B2 [Occ=Once] :: b_12) ->
case v_B1 of { __DEFAULT -> v1_B2 }}]
f = \ (@ a_11) (@ b_12) (v_B1 :: a_11) (v1_B2 :: b_12) ->
case v_B1 of { __DEFAULT -> v1_B2 }
The strictness signature says that it puts the same demand on the first argument as it puts on the second argument, which clearly is wrong, or at least too conservative! I rather expected the signature <S,1*HU><S,1*U>
, where HU
stands for "head-used" (the origins of the term are probably in https://link.springer.com/chapter/10.1007/3-540-18317-5_21, which has a different semantics for that term), which means "not used any deeper than WHNF". Which is exactly the demand seq
puts its first argument under. Clearly, it's funny not to give seq
a head-used demand!
I don't think there currently is a way to produce HU
.