compileExp :: Expr Var -> Compile Expression
compileExp exp = (>>= optimizeApp) $
  case exp of
    Var var -> fmap Variable (compileVar var)
    Lit lit -> compileLit lit
    App op arg -> compileApp op arg
    Lam var exp -> compileLam var exp
    Let bind exp -> compileLet bind exp
    Cast exp _ -> compileExp exp
    Case exp var typ alts -> compileCase exp var typ alts
compileExp :: Expr Var -> Compile Expression
compileExp exp = (>>= optimizeApp) $
  case exp of
    Var var -> fmap Variable (compileVar var)
    Lit lit -> compileLit lit
    App op arg -> compileApp op arg
    Lam var exp -> compileLam var exp
    Let bind exp -> compileLet bind exp
    Cast exp _ -> compileExp exp
    Case exp var typ alts -> compileCase exp var typ alts
compileExp exp = (>>= optimizeApp) $
  case exp of
    Var var -> fmap Variable (compileVar var)
    Lit lit -> compileLit lit
    App op arg -> compileApp op arg
    Lam var exp -> compileLam var exp
    Let bind exp -> compileLet bind exp
    Cast exp _ -> compileExp exp
    Case exp var typ alts -> compileCase exp var typ alts