+\begin{pseudocode}
+etaExpand :: Int -- Add this number of value args
+ -> UniquSupply
+ -> CoreExpr -> Type -- Expression and its type
+ -> CoreEpxr
+
+-- 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 arg' (etaExpand (n-1) us2 (App expr (Var arg')) res_ty)
+ where
+ arg' = mkSysLocal SLIT("eta") uniq arg_ty
+ (us1, us2) = splitUnqiSupply 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
+ }}}
+\end{pseudocode}
+
+