    -----------------------------------------------------------------------------
    -- |
    -- Module      :  Language.Haskell.Exts.Build
    -- Copyright   :  (c) The GHC Team, 1997-2000,
    --                (c) Niklas Broberg 2004
    -- License     :  BSD-style (see the file LICENSE.txt)
    --
    -- Maintainer  :  Niklas Broberg, d00nibro@chalmers.se
    -- Stability   :  experimental
    -- Portability :  portable
    --
    -- This module contains combinators to use when building
    -- Haskell source trees programmatically, as opposed to
    -- parsing them from a string. The contents here are quite
    -- experimental and will likely receive a lot of attention
    -- when the rest has stabilised.
    --
    -----------------------------------------------------------------------------

    module Language.Haskell.Exts.Build (

        -- * Syntax building functions
        name,       -- :: String -> Name ()
        sym,        -- :: String -> Name ()
        var,        -- :: Name () -> Exp ()
        op,         -- :: Name () -> QOp
        qvar,       -- :: Module -> Name () -> Exp ()
        pvar,       -- :: Name () -> Pat ()
        app,        -- :: Exp () -> Exp () -> Exp ()
        infixApp,   -- :: Exp () -> QOp -> Exp () -> Exp ()
        appFun,     -- :: Exp () -> [Exp] -> Exp ()
        pApp,       -- :: Name () -> [Pat] -> Pat ()
        tuple,      -- :: [Exp] -> Exp ()
        pTuple,     -- :: [Pat] -> Pat ()
        varTuple,   -- :: [Name] -> Exp ()
        pvarTuple,  -- :: [Name] -> Pat ()
        function,   -- :: String -> Exp ()
        strE,       -- :: String -> Exp ()
        charE,      -- :: Char -> Exp ()
        intE,       -- :: Integer -> Exp ()
        strP,       -- :: String -> Pat ()
        charP,      -- :: Char -> Pat ()
        intP,       -- :: Integer -> Pat ()
        doE,        -- :: [Stmt] -> Exp ()
        lamE,       -- :: SrcLoc -> [Pat] -> Exp () -> Exp ()
        letE,       -- :: [Decl] -> Exp () -> Exp ()
        caseE,      -- :: Exp () -> [Alt] -> Exp ()
        alt,        -- :: SrcLoc -> Pat () -> Exp () -> Alt
        altGW,      -- :: SrcLoc -> Pat () -> [Stmt] -> Exp () -> Binds -> Alt
        listE,      -- :: [Exp] -> Exp ()
        eList,      -- :: Exp ()
        peList,     -- :: Pat ()
        paren,      -- :: Exp () -> Exp ()
        pParen,     -- :: Pat () -> Pat ()
        qualStmt,   -- :: Exp () -> Stmt
        genStmt,    -- :: SrcLoc -> Pat () -> Exp () -> Stmt
        letStmt,    -- :: [Decl] -> Stmt
        binds,      -- :: [Decl] -> Binds
        noBinds,    -- :: Binds
        wildcard,   -- :: Pat ()
        genNames,   -- :: String -> Int -> [Name]

        -- * More advanced building
        sfun,           -- :: SrcLoc -> Name () -> [Name] -> Rhs -> Binds -> Decl ()
        simpleFun,      -- :: SrcLoc -> Name () -> Name () -> Exp () -> Decl ()
        patBind,        -- :: SrcLoc -> Pat () -> Exp () -> Decl ()
        patBindWhere,   -- :: SrcLoc -> Pat () -> Exp () -> [Decl] -> Decl ()
        nameBind,       -- :: SrcLoc -> Name () -> Exp () -> Decl ()
        metaFunction,   -- :: String -> [Exp] -> Exp ()
        metaConPat      -- :: String -> [Pat] -> Pat ()
      ) where

    import Language.Haskell.Exts.Syntax

    -----------------------------------------------------------------------------
    -- Help functions for Abstract syntax

    -- | An identifier with the given string as its name.
    --   The string should be a valid Haskell identifier.
    name :: String -> Name ()
    name :: String -> Name ()
    name = () -> String -> Name ()
    forall l. l -> String -> Name l
    Ident ()

    -- | A symbol identifier. The string should be a valid
    --   Haskell symbol identifier.
    sym :: String -> Name ()
    sym :: String -> Name ()
    sym = () -> String -> Name ()
    forall l. l -> String -> Name l
    Symbol ()

    -- | A local variable as expression.
    var :: Name () -> Exp ()
    var :: Name () -> Exp ()
    var = () -> QName () -> Exp ()
    forall l. l -> QName l -> Exp l
    Var () (QName () -> Exp ()) -> (Name () -> QName ()) -> Name () -> Exp ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . () -> Name () -> QName ()
    forall l. l -> Name l -> QName l
    UnQual ()

    -- | Use the given identifier as an operator.
    op :: Name () -> QOp ()
    op :: Name () -> QOp ()
    op = () -> QName () -> QOp ()
    forall l. l -> QName l -> QOp l
    QVarOp () (QName () -> QOp ()) -> (Name () -> QName ()) -> Name () -> QOp ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . () -> Name () -> QName ()
    forall l. l -> Name l -> QName l
    UnQual ()

    -- | A qualified variable as expression.
    qvar :: ModuleName () -> Name () -> Exp ()
    qvar :: ModuleName () -> Name () -> Exp ()
    qvar ModuleName ()
    m Name ()
    n = () -> QName () -> Exp ()
    forall l. l -> QName l -> Exp l
    Var () (QName () -> Exp ()) -> QName () -> Exp ()
    forall a b. (a -> b) -> a -> b
    $ () -> ModuleName () -> Name () -> QName ()
    forall l. l -> ModuleName l -> Name l -> QName l
    Qual () ModuleName ()
    m Name ()
    n

    -- | A pattern variable.
    pvar :: Name () -> Pat ()
    pvar :: Name () -> Pat ()
    pvar = () -> Name () -> Pat ()
    forall l. l -> Name l -> Pat l
    PVar ()

    -- | Application of expressions by juxtaposition.
    app :: Exp () -> Exp () -> Exp ()
    app :: Exp () -> Exp () -> Exp ()
    app = () -> Exp () -> Exp () -> Exp ()
    forall l. l -> Exp l -> Exp l -> Exp l
    App ()

    -- | Apply an operator infix.
    infixApp :: Exp () -> QOp () -> Exp () -> Exp ()
    infixApp :: Exp () -> QOp () -> Exp () -> Exp ()
    infixApp = () -> Exp () -> QOp () -> Exp () -> Exp ()
    forall l. l -> Exp l -> QOp l -> Exp l -> Exp l
    InfixApp ()

    -- | Apply a function to a list of arguments.
    appFun :: Exp () -> [Exp ()] -> Exp ()
    appFun :: Exp () -> [Exp ()] -> Exp ()
    appFun Exp ()
    f [] = Exp ()
    f
    appFun Exp ()
    f (Exp ()
    a:[Exp ()]
    as) = Exp () -> [Exp ()] -> Exp ()
    appFun (Exp () -> Exp () -> Exp ()
    app Exp ()
    f Exp ()
    a) [Exp ()]
    as

    -- | A constructor pattern, with argument patterns.
    pApp :: Name () -> [Pat ()] -> Pat ()
    pApp :: Name () -> [Pat ()] -> Pat ()
    pApp Name ()
    n [Pat ()]
    ps = () -> QName () -> [Pat ()] -> Pat ()
    forall l. l -> QName l -> [Pat l] -> Pat l
    PApp () (() -> Name () -> QName ()
    forall l. l -> Name l -> QName l
    UnQual () Name ()
    n) [Pat ()]
    ps

    -- | A tuple expression.
    tuple :: [Exp ()] -> Exp ()
    tuple :: [Exp ()] -> Exp ()
    tuple = () -> Boxed -> [Exp ()] -> Exp ()
    forall l. l -> Boxed -> [Exp l] -> Exp l
    Tuple () Boxed
    Boxed

    -- | A tuple pattern.
    pTuple :: [Pat ()] -> Pat ()
    pTuple :: [Pat ()] -> Pat ()
    pTuple = () -> Boxed -> [Pat ()] -> Pat ()
    forall l. l -> Boxed -> [Pat l] -> Pat l
    PTuple () Boxed
    Boxed

    -- | A tuple expression consisting of variables only.
    varTuple :: [Name ()] -> Exp ()
    varTuple :: [Name ()] -> Exp ()
    varTuple [Name ()]
    ns = [Exp ()] -> Exp ()
    tuple ([Exp ()] -> Exp ()) -> [Exp ()] -> Exp ()
    forall a b. (a -> b) -> a -> b
    $ (Name () -> Exp ()) -> [Name ()] -> [Exp ()]
    forall a b. (a -> b) -> [a] -> [b]
    map Name () -> Exp ()
    var [Name ()]
    ns

    -- | A tuple pattern consisting of variables only.
    pvarTuple :: [Name ()] -> Pat ()
    pvarTuple :: [Name ()] -> Pat ()
    pvarTuple [Name ()]
    ns = [Pat ()] -> Pat ()
    pTuple ([Pat ()] -> Pat ()) -> [Pat ()] -> Pat ()
    forall a b. (a -> b) -> a -> b
    $ (Name () -> Pat ()) -> [Name ()] -> [Pat ()]
    forall a b. (a -> b) -> [a] -> [b]
    map Name () -> Pat ()
    pvar [Name ()]
    ns

    -- | A function with a given name.
    function :: String -> Exp ()
    function :: String -> Exp ()
    function = Name () -> Exp ()
    var (Name () -> Exp ()) -> (String -> Name ()) -> String -> Exp ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . () -> String -> Name ()
    forall l. l -> String -> Name l
    Ident ()

    -- | A literal string expression.
    strE :: String -> Exp ()
    strE :: String -> Exp ()
    strE String
    s = () -> Literal () -> Exp ()
    forall l. l -> Literal l -> Exp l
    Lit () (() -> String -> String -> Literal ()
    forall l. l -> String -> String -> Literal l
    String () String
    s String
    s)

    -- | A literal character expression.
    charE :: Char -> Exp ()
    charE :: Char -> Exp ()
    charE Char
    c = () -> Literal () -> Exp ()
    forall l. l -> Literal l -> Exp l
    Lit () (() -> Char -> String -> Literal ()
    forall l. l -> Char -> String -> Literal l
    Char () Char
    c [Char
    c])

    -- | A literal integer expression.
    intE :: Integer -> Exp ()
    intE :: Integer -> Exp ()
    intE Integer
    n = () -> Literal () -> Exp ()
    forall l. l -> Literal l -> Exp l
    Lit () (() -> Integer -> String -> Literal ()
    forall l. l -> Integer -> String -> Literal l
    Int () Integer
    n (Integer -> String
    forall a. Show a => a -> String
    show Integer
    n))

    -- | A literal string pattern.
    strP :: String -> Pat ()
    strP :: String -> Pat ()
    strP String
    s = () -> Sign () -> Literal () -> Pat ()
    forall l. l -> Sign l -> Literal l -> Pat l
    PLit () (() -> Sign ()
    forall l. l -> Sign l
    Signless ()) (() -> String -> String -> Literal ()
    forall l. l -> String -> String -> Literal l
    String () String
    s String
    s)

    -- | A literal character pattern.
    charP :: Char -> Pat ()
    charP :: Char -> Pat ()
    charP Char
    x = () -> Sign () -> Literal () -> Pat ()
    forall l. l -> Sign l -> Literal l -> Pat l
    PLit () (() -> Sign ()
    forall l. l -> Sign l
    Signless ()) (() -> Char -> String -> Literal ()
    forall l. l -> Char -> String -> Literal l
    Char () Char
    x [Char
    x])

    -- | A literal integer pattern.
    intP :: Integer -> Pat ()
    intP :: Integer -> Pat ()
    intP Integer
    x = () -> Sign () -> Literal () -> Pat ()
    forall l. l -> Sign l -> Literal l -> Pat l
    PLit ()
              (if Integer
    x Integer -> Integer -> Bool
    forall a. Ord a => a -> a -> Bool
    >= Integer
    0 then () -> Sign ()
    forall l. l -> Sign l
    Signless () else () -> Sign ()
    forall l. l -> Sign l
    Negative ())
              (() -> Integer -> String -> Literal ()
    forall l. l -> Integer -> String -> Literal l
    Int () (Integer -> Integer
    forall a. Num a => a -> a
    abs Integer
    x) (Integer -> String
    forall a. Show a => a -> String
    show Integer
    x))

    -- | A do block formed by the given statements.
    --   The last statement in the list should be
    --   a 'Qualifier' expression.
    doE :: [Stmt ()] -> Exp ()
    doE :: [Stmt ()] -> Exp ()
    doE = () -> [Stmt ()] -> Exp ()
    forall l. l -> [Stmt l] -> Exp l
    Do ()

    -- | Lambda abstraction, given a list of argument
    --   patterns and an expression body.
    lamE :: [Pat ()] -> Exp () -> Exp ()
    lamE :: [Pat ()] -> Exp () -> Exp ()
    lamE = () -> [Pat ()] -> Exp () -> Exp ()
    forall l. l -> [Pat l] -> Exp l -> Exp l
    Lambda ()

    -- | A @let@ ... @in@ block.
    letE :: [Decl ()] -> Exp () -> Exp ()
    letE :: [Decl ()] -> Exp () -> Exp ()
    letE [Decl ()]
    ds Exp ()
    e = () -> Binds () -> Exp () -> Exp ()
    forall l. l -> Binds l -> Exp l -> Exp l
    Let () ([Decl ()] -> Binds ()
    binds [Decl ()]
    ds) Exp ()
    e

    -- | A @case@ expression.
    caseE :: Exp () -> [Alt ()] -> Exp ()
    caseE :: Exp () -> [Alt ()] -> Exp ()
    caseE = () -> Exp () -> [Alt ()] -> Exp ()
    forall l. l -> Exp l -> [Alt l] -> Exp l
    Case ()

    -- | An unguarded alternative in a @case@ expression.
    alt :: Pat () -> Exp () -> Alt ()
    alt :: Pat () -> Exp () -> Alt ()
    alt Pat ()
    p Exp ()
    e = () -> Pat () -> Rhs () -> Maybe (Binds ()) -> Alt ()
    forall l. l -> Pat l -> Rhs l -> Maybe (Binds l) -> Alt l
    Alt () Pat ()
    p (Exp () -> Rhs ()
    unGAlt Exp ()
    e) Maybe (Binds ())
    noBinds

    -- | An alternative with a single guard in a @case@ expression.
    altGW :: Pat () -> [Stmt ()] -> Exp () -> Binds () -> Alt ()
    altGW :: Pat () -> [Stmt ()] -> Exp () -> Binds () -> Alt ()
    altGW Pat ()
    p [Stmt ()]
    gs Exp ()
    e Binds ()
    w = () -> Pat () -> Rhs () -> Maybe (Binds ()) -> Alt ()
    forall l. l -> Pat l -> Rhs l -> Maybe (Binds l) -> Alt l
    Alt () Pat ()
    p ([Stmt ()] -> Exp () -> Rhs ()
    gAlt [Stmt ()]
    gs Exp ()
    e) (Binds () -> Maybe (Binds ())
    forall a. a -> Maybe a
    Just Binds ()
    w)

    -- | An unguarded righthand side of a @case@ alternative.
    unGAlt :: Exp () -> Rhs ()
    unGAlt :: Exp () -> Rhs ()
    unGAlt = () -> Exp () -> Rhs ()
    forall l. l -> Exp l -> Rhs l
    UnGuardedRhs ()

    -- | An list of guarded righthand sides for a @case@ alternative.
    gAlts :: [([Stmt ()],Exp ())] -> Rhs ()
    gAlts :: [([Stmt ()], Exp ())] -> Rhs ()
    gAlts [([Stmt ()], Exp ())]
    as = () -> [GuardedRhs ()] -> Rhs ()
    forall l. l -> [GuardedRhs l] -> Rhs l
    GuardedRhss () ([GuardedRhs ()] -> Rhs ()) -> [GuardedRhs ()] -> Rhs ()
    forall a b. (a -> b) -> a -> b
    $ (([Stmt ()], Exp ()) -> GuardedRhs ())
    -> [([Stmt ()], Exp ())] -> [GuardedRhs ()]
    forall a b. (a -> b) -> [a] -> [b]
    map (\([Stmt ()]
    gs,Exp ()
    e) -> () -> [Stmt ()] -> Exp () -> GuardedRhs ()
    forall l. l -> [Stmt l] -> Exp l -> GuardedRhs l
    GuardedRhs () [Stmt ()]
    gs Exp ()
    e) [([Stmt ()], Exp ())]
    as

    -- | A single guarded righthand side for a @case@ alternative.
    gAlt :: [Stmt ()] -> Exp () -> Rhs ()
    gAlt :: [Stmt ()] -> Exp () -> Rhs ()
    gAlt [Stmt ()]
    gs Exp ()
    e = [([Stmt ()], Exp ())] -> Rhs ()
    gAlts [([Stmt ()]
    gs,Exp ()
    e)]

    -- | A list expression.
    listE :: [Exp ()] -> Exp ()
    listE :: [Exp ()] -> Exp ()
    listE = () -> [Exp ()] -> Exp ()
    forall l. l -> [Exp l] -> Exp l
    List ()

    -- | The empty list expression.
    eList :: Exp ()
    eList :: Exp ()
    eList = () -> [Exp ()] -> Exp ()
    forall l. l -> [Exp l] -> Exp l
    List () []

    -- | The empty list pattern.
    peList :: Pat ()
    peList :: Pat ()
    peList = () -> [Pat ()] -> Pat ()
    forall l. l -> [Pat l] -> Pat l
    PList () []

    -- | Put parentheses around an expression.
    paren :: Exp () -> Exp ()
    paren :: Exp () -> Exp ()
    paren = () -> Exp () -> Exp ()
    forall l. l -> Exp l -> Exp l
    Paren ()

    -- | Put parentheses around a pattern.
    pParen :: Pat () -> Pat ()
    pParen :: Pat () -> Pat ()
    pParen = () -> Pat () -> Pat ()
    forall l. l -> Pat l -> Pat l
    PParen ()

    -- | A qualifier expression statement.
    qualStmt :: Exp () -> Stmt ()
    qualStmt :: Exp () -> Stmt ()
    qualStmt = () -> Exp () -> Stmt ()
    forall l. l -> Exp l -> Stmt l
    Qualifier ()

    -- | A generator statement: /pat/ @<-@ /exp/
    genStmt :: Pat () -> Exp () -> Stmt ()
    genStmt :: Pat () -> Exp () -> Stmt ()
    genStmt = () -> Pat () -> Exp () -> Stmt ()
    forall l. l -> Pat l -> Exp l -> Stmt l
    Generator ()

    -- | A @let@ binding group as a statement.
    letStmt :: [Decl ()] -> Stmt ()
    letStmt :: [Decl ()] -> Stmt ()
    letStmt [Decl ()]
    ds = () -> Binds () -> Stmt ()
    forall l. l -> Binds l -> Stmt l
    LetStmt () (Binds () -> Stmt ()) -> Binds () -> Stmt ()
    forall a b. (a -> b) -> a -> b
    $ [Decl ()] -> Binds ()
    binds [Decl ()]
    ds

    -- | Hoist a set of declarations to a binding group.
    binds :: [Decl ()] -> Binds ()
    binds :: [Decl ()] -> Binds ()
    binds = () -> [Decl ()] -> Binds ()
    forall l. l -> [Decl l] -> Binds l
    BDecls ()

    -- | An empty binding group.
    noBinds :: Maybe (Binds ())
    noBinds :: Maybe (Binds ())
    noBinds = Maybe (Binds ())
    forall a. Maybe a
    Nothing

    -- | The wildcard pattern: @_@
    wildcard :: Pat ()
    wildcard :: Pat ()
    wildcard = () -> Pat ()
    forall l. l -> Pat l
    PWildCard ()

    -- | Generate k names by appending numbers 1 through k to a given string.
    genNames :: String -> Int -> [Name ()]
    genNames :: String -> Int -> [Name ()]
    genNames String
    s Int
    k = [ () -> String -> Name ()
    forall l. l -> String -> Name l
    Ident () (String -> Name ()) -> String -> Name ()
    forall a b. (a -> b) -> a -> b
    $ String
    s String -> String -> String
    forall a. [a] -> [a] -> [a]
    ++ Int -> String
    forall a. Show a => a -> String
    show Int
    i | Int
    i <- [Int
    1..Int
    k] ]

    -------------------------------------------------------------------------------
    -- Some more specialised help functions

    -- | A function with a single clause
    sfun :: Name () -> [Name ()] -> (Rhs ()) -> Maybe (Binds ()) -> Decl ()
    sfun :: Name () -> [Name ()] -> Rhs () -> Maybe (Binds ()) -> Decl ()
    sfun Name ()
    f [Name ()]
    pvs Rhs ()
    rhs Maybe (Binds ())
    bs = () -> [Match ()] -> Decl ()
    forall l. l -> [Match l] -> Decl l
    FunBind () [() -> Name () -> [Pat ()] -> Rhs () -> Maybe (Binds ()) -> Match ()
    forall l.
    l -> Name l -> [Pat l] -> Rhs l -> Maybe (Binds l) -> Match l
    Match () Name ()
    f ((Name () -> Pat ()) -> [Name ()] -> [Pat ()]
    forall a b. (a -> b) -> [a] -> [b]
    map Name () -> Pat ()
    pvar [Name ()]
    pvs) Rhs ()
    rhs Maybe (Binds ())
    bs]

    -- | A function with a single clause, a single argument, no guards
    -- and no where declarations
    simpleFun :: Name () -> Name () -> Exp () -> Decl ()
    simpleFun :: Name () -> Name () -> Exp () -> Decl ()
    simpleFun Name ()
    f Name ()
    a Exp ()
    e = let rhs :: Rhs ()
    rhs = () -> Exp () -> Rhs ()
    forall l. l -> Exp l -> Rhs l
    UnGuardedRhs () Exp ()
    e
                 in Name () -> [Name ()] -> Rhs () -> Maybe (Binds ()) -> Decl ()
    sfun Name ()
    f [Name ()
    a] Rhs ()
    rhs Maybe (Binds ())
    noBinds

    -- | A pattern bind where the pattern is a variable, and where
    -- there are no guards and no 'where' clause.
    patBind :: Pat () -> Exp () -> Decl ()
    patBind :: Pat () -> Exp () -> Decl ()
    patBind Pat ()
    p Exp ()
    e = let rhs :: Rhs ()
    rhs = () -> Exp () -> Rhs ()
    forall l. l -> Exp l -> Rhs l
    UnGuardedRhs () Exp ()
    e
             in () -> Pat () -> Rhs () -> Maybe (Binds ()) -> Decl ()
    forall l. l -> Pat l -> Rhs l -> Maybe (Binds l) -> Decl l
    PatBind () Pat ()
    p Rhs ()
    rhs Maybe (Binds ())
    noBinds

    -- | A pattern bind where the pattern is a variable, and where
    -- there are no guards, but with a 'where' clause.
    patBindWhere :: Pat () -> Exp () -> [Decl ()] -> Decl ()
    patBindWhere :: Pat () -> Exp () -> [Decl ()] -> Decl ()
    patBindWhere Pat ()
    p Exp ()
    e [Decl ()]
    ds = let rhs :: Rhs ()
    rhs = () -> Exp () -> Rhs ()
    forall l. l -> Exp l -> Rhs l
    UnGuardedRhs () Exp ()
    e
                 in () -> Pat () -> Rhs () -> Maybe (Binds ()) -> Decl ()
    forall l. l -> Pat l -> Rhs l -> Maybe (Binds l) -> Decl l
    PatBind () Pat ()
    p Rhs ()
    rhs (if [Decl ()] -> Bool
    forall a. [a] -> Bool
    forall (t :: * -> *) a. Foldable t => t a -> Bool
    null [Decl ()]
    ds then Maybe (Binds ())
    forall a. Maybe a
    Nothing else Binds () -> Maybe (Binds ())
    forall a. a -> Maybe a
    Just ([Decl ()] -> Binds ()
    binds [Decl ()]
    ds))

    -- | Bind an identifier to an expression.
    nameBind :: Name () -> Exp () -> Decl ()
    nameBind :: Name () -> Exp () -> Decl ()
    nameBind Name ()
    n Exp ()
    e = Pat () -> Exp () -> Decl ()
    patBind (Name () -> Pat ()
    pvar Name ()
    n) Exp ()
    e

    -- | Apply function of a given name to a list of arguments.
    metaFunction :: String -> [Exp ()] -> Exp ()
    metaFunction :: String -> [Exp ()] -> Exp ()
    metaFunction String
    s' [Exp ()]
    es' = String -> [Exp ()] -> Exp ()
    mf String
    s' ([Exp ()] -> [Exp ()]
    forall a. [a] -> [a]
    reverse [Exp ()]
    es')
      where mf :: String -> [Exp ()] -> Exp ()
    mf String
    s []     = Name () -> Exp ()
    var (Name () -> Exp ()) -> Name () -> Exp ()
    forall a b. (a -> b) -> a -> b
    $ String -> Name ()
    name String
    s
            mf String
    s (Exp ()
    e:[Exp ()]
    es) = Exp () -> Exp () -> Exp ()
    app (String -> [Exp ()] -> Exp ()
    mf String
    s [Exp ()]
    es) Exp ()
    e

    -- | Apply a constructor of a given name to a list of pattern
    --   arguments, forming a constructor pattern.
    metaConPat :: String -> [Pat ()] -> Pat ()
    metaConPat :: String -> [Pat ()] -> Pat ()
    metaConPat String
    s [Pat ()]
    ps = Name () -> [Pat ()] -> Pat ()
    pApp (String -> Name ()
    name String
    s) [Pat ()]
    ps