+exprEtaExpandArity :: CoreExpr -> (Int, Bool)
+-- The Int is number of value args the thing can be
+-- applied to without doing much work
+-- The Bool is True iff there are enough explicit value lambdas
+-- at the top to make this arity apparent
+-- (but ignore it when arity==0)
+
+-- 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
+
+exprEtaExpandArity e
+ = go 0 e
+ where
+ go ar (Lam x e) | isId x = go (ar+1) e
+ | otherwise = go ar e
+ go ar (Note n e) | ok_note n = go ar e
+ go ar other = (ar + ar', ar' == 0)
+ where
+ ar' = go1 other `max` 0
+
+ go1 (Var v) = idArity v
+ go1 (Lam x e) | isId x = go1 e + 1
+ | otherwise = go1 e
+ go1 (Note n e) | ok_note n = go1 e
+ go1 (App f (Type _)) = go1 f
+ go1 (App f a) | exprIsCheap a = go1 f - 1
+ go1 (Case scrut _ alts)
+ | exprIsCheap scrut = min_zero [go1 rhs | (_,_,rhs) <- alts]
+ go1 (Let b e)
+ | all exprIsCheap (rhssOfBind b) = go1 e
+
+ go1 other = 0
+
+ ok_note (Coerce _ _) = True
+ ok_note InlineCall = True
+ ok_note other = False
+ -- Notice that we do not look through __inline_me__
+ -- 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
+
+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
+
+\end{code}
+
+
+\begin{code}
+etaExpand :: Int -- Add this number of value args
+ -> UniqSupply
+ -> CoreExpr -> Type -- Expression and its type
+ -> CoreExpr
+-- (etaExpand n us e ty) returns an expression with
+-- the same meaning as 'e', but with arity 'n'.
+
+-- Given e' = etaExpand n us e ty
+-- We should have
+-- ty = exprType e = exprType e'
+--
+-- etaExpand deals with for-alls and coerces. For example:
+-- etaExpand 1 E
+-- where E :: forall a. T
+-- newtype T = MkT (A -> B)
+--
+-- would return
+-- (/\b. coerce T (\y::A -> (coerce (A->B) (E b) y)
+
+-- (case x of { I# x -> /\ a -> coerce T E)
+
+etaExpand n us expr ty
+ | n == 0 -- Saturated, so nothing to do
+ = expr
+
+ | otherwise -- An unsaturated constructor or primop; eta expand it
+ = case splitForAllTy_maybe ty of {
+ Just (tv,ty') -> Lam tv (etaExpand n us (App expr (Type (mkTyVarTy tv))) ty')
+
+ ; Nothing ->
+
+ case splitFunTy_maybe ty of {
+ Just (arg_ty, res_ty) -> Lam arg1 (etaExpand (n-1) us2 (App expr (Var arg1)) res_ty)
+ where
+ arg1 = mkSysLocal SLIT("eta") uniq arg_ty
+ (us1, us2) = splitUniqSupply us
+ uniq = uniqFromSupply us1
+
+ ; Nothing ->
+
+ case splitNewType_maybe ty of {
+ Just ty' -> mkCoerce ty ty' (etaExpand n us (mkCoerce ty' ty expr) ty') ;
+
+ Nothing -> pprTrace "Bad eta expand" (ppr expr $$ ppr ty) expr
+ }}}