+exprArity (Lam b e) | isTyVar b = exprArity e
+ | otherwise = 1 + exprArity e
+exprArity (Note note e) | ok_note note = exprArity e
+exprArity other = 0
+\end{code}
+
+
+\begin{code}
+exprGenerousArity :: CoreExpr -> Int -- The number of args the thing can be applied to
+ -- without doing much work
+-- This is used when eta expanding
+-- e ==> \xy -> e x y
+--
+-- It returns 1 (or more) to:
+-- case x of p -> \s -> ...
+-- because for I/O ish things we really want to get that \s to the top.
+-- We are prepared to evaluate x each time round the loop in order to get that
+-- Hence "generous" arity
+
+exprGenerousArity (Var v) = arityLowerBound (getIdArity v)
+exprGenerousArity (Note note e)
+ | ok_note note = exprGenerousArity e
+exprGenerousArity (Lam x e)
+ | isId x = 1 + exprGenerousArity e
+ | otherwise = exprGenerousArity e
+exprGenerousArity (Let bind body)
+ | all exprIsCheap (rhssOfBind bind) = exprGenerousArity body
+exprGenerousArity (Case scrut _ alts)
+ | exprIsCheap scrut = min_zero [exprGenerousArity rhs | (_,_,rhs) <- alts]
+exprGenerousArity other = 0 -- Could do better for applications
+
+min_zero :: [Int] -> Int -- Find the minimum, but zero is the smallest
+min_zero (x:xs) = go x xs
+ where
+ go 0 xs = 0 -- Nothing beats zero
+ go min [] = min
+ go min (x:xs) | x < min = go x xs
+ | otherwise = go min xs
+
+ok_note (SCC _) = False -- (Over?) conservative
+ok_note (TermUsg _) = False -- Doesn't matter much
+
+ok_note (Coerce _ _) = True
+ -- We *do* look through coerces when getting arities.
+ -- Reason: arities are to do with *representation* and
+ -- work duplication.
+
+ok_note InlineCall = True
+ok_note InlineMe = False
+ -- This one is a bit more surprising, but consider
+ -- f = _inline_me (\x -> e)
+ -- We DO NOT want to eta expand this to
+ -- f = \x -> (_inline_me (\x -> e)) x
+ -- because the _inline_me gets dropped now it is applied,
+ -- giving just
+ -- f = \x -> e
+ -- A Bad Idea