Note [Arity invariants for bindings]
We have the following invariants for let-bindings
(1) In any binding f = e,
idArity f <= typeArity (idType f)
We enforce this with trimArityType, called in findRhsArity;
see Note [Arity trimming].
Note that we enforce this only for /bindings/. We do /not/ insist that
arityTypeArity (arityType e) <= typeArity (exprType e)
because that is quite a bit more expensive to guaranteed; it would
mean checking at every Cast in the recursive arityType, for example.
(2) If typeArity (exprType e) = n,
then manifestArity (etaExpand e n) = n
That is, etaExpand can always expand as much as typeArity says
(or less, of course). So the case analysis in etaExpand and in
typeArity must match.
Consequence: because of (1), if we eta-expand to (idArity f), we will
end up with n manifest lambdas.
(3) In any binding f = e,
idArity f <= arityTypeArity (safeArityType (arityType e))
That is, we call safeArityType before attributing e's arityType to f.
See Note [SafeArityType].
So we call safeArityType in findRhsArity.
Suppose we have
f :: Int -> Int -> Int
f x y = x+y -- Arity 2
g :: F Int
g = case <cond> of { True -> f |> co1
; False -> g |> co2 }
where F is a type family. Now, we can't eta-expand g to have arity 2,
because etaExpand, which works off the /type/ of the expression
(albeit looking through newtypes), doesn't know how to make an
eta-expanded binding
g = (\a b. case x of ...) |> co
because it can't make up `co` or the types of `a` and `b`.
So invariant (1) ensures that every binding has an arity that is no greater
than the typeArity of the RHS; and invariant (2) ensures that etaExpand
and handle what typeArity says.
Why is this important? Because
- In GHC.Iface.Tidy we use exprArity/manifestArity to fix the *final
arity* of each top-level Id, and in
- In CorePrep we use etaExpand on each rhs, so that the visible
lambdas actually match that arity, which in turn means that the
StgRhs has a number of lambdas that precisely matches the arity. References 2
- Arity trimming GHC.Core.Opt.Arity
- SafeArityType GHC.Core.Opt.Arity
Referenced by 6
- GHC.Core.Opt.Arity call site ×2
- GHC.Core.Lint call site
- Arity trimming GHC.Core.Opt.Arity
- Don't eta expand in w/w GHC.Core.Opt.WorkWrap
- GHC.Iface.Tidy call site