compileApp :: Expr Var -> Expr Var -> Compile Expression
compileApp op arg = do
  case arg of
    Type{} -> compileExp op
    _ -> do
      case op of
        Var v | any ((== printName (varName v)) . printNameParts) noops -> compileExp arg
        (App (Var v') Type{})
          | printName (varName v') == "base:Control.Exception.Base.patError"
          , Lit (MachStr fs) <- arg -> compilePatError (fastStringToText fs)
          | printName (varName v') == "base:GHC.Err.error" -> compileUserError arg
        _ -> do
          o <- compileExp op
          a <- compileExp arg
          case o of
            Apply (Variable ident) [_]
              | elem ident (map (Identifier . encodeNameParts) methods) -> return (Apply o [a])
            _ -> return (Apply (force o) [a])
compileApp :: Expr Var -> Expr Var -> Compile Expression
compileApp op arg = do
  case arg of
    Type{} -> compileExp op
    _ -> do
      case op of
        Var v | any ((== printName (varName v)) . printNameParts) noops -> compileExp arg
        (App (Var v') Type{})
          | printName (varName v') == "base:Control.Exception.Base.patError"
          , Lit (MachStr fs) <- arg -> compilePatError (fastStringToText fs)
          | printName (varName v') == "base:GHC.Err.error" -> compileUserError arg
        _ -> do
          o <- compileExp op
          a <- compileExp arg
          case o of
            Apply (Variable ident) [_]
              | elem ident (map (Identifier . encodeNameParts) methods) -> return (Apply o [a])
            _ -> return (Apply (force o) [a])
compileApp op arg = do
  case arg of
    Type{} -> compileExp op
    _ -> do
      case op of
        Var v | any ((== printName (varName v)) . printNameParts) noops -> compileExp arg
        (App (Var v') Type{})
          | printName (varName v') == "base:Control.Exception.Base.patError"
          , Lit (MachStr fs) <- arg -> compilePatError (fastStringToText fs)
          | printName (varName v') == "base:GHC.Err.error" -> compileUserError arg
        _ -> do
          o <- compileExp op
          a <- compileExp arg
          case o of
            Apply (Variable ident) [_]
              | elem ident (map (Identifier . encodeNameParts) methods) -> return (Apply o [a])
            _ -> return (Apply (force o) [a])