    {-# LANGUAGE CPP, GeneralizedNewtypeDeriving #-}
    module Text.ParserCombinators.Poly.Lazy
      ( -- * The Parser datatype
        Parser(P)   -- datatype, instance of: Functor, Monad, PolyParse
      , Result(..)  -- internal to the parser monad
      , runParser   -- :: Parser t a -> [t] -> (Either String a, [t])
        -- ** Basic parsers
      , next        -- :: Parser t t
      , eof         -- :: Parser t ()
      , satisfy     -- :: (t->Bool) -> Parser t t
      , satisfyMsg  -- :: (t->Bool) -> String -> Parser t t
      , onFail      -- :: Parser t a -> Parser t a -> Parser t a

        -- ** Re-parsing
      , reparse     -- :: [t] -> Parser t ()
        -- * Re-export all more general combinators
      , module Text.ParserCombinators.Poly.Base
      , module Control.Applicative
      ) where

    import Text.ParserCombinators.Poly.Base
    import Text.ParserCombinators.Poly.Result
    import qualified Text.ParserCombinators.Poly.Parser as P
    import Control.Applicative
    import qualified Control.Monad.Fail as Fail

    #if __GLASGOW_HASKELL__
    import Control.Exception hiding (bracket)
    throwE :: String -> a
    throwE :: forall a. String -> a
    throwE String
    msg = ErrorCall -> a
    forall a e. (HasCallStack, Exception e) => e -> a
    throw (String -> ErrorCall
    ErrorCall String
    msg)
    #else
    throwE :: String -> a
    throwE msg = error msg
    #endif

    -- | The only differences between a Plain and a Lazy parser are the instance
    --   of Applicative, and the type (and implementation) of runParser.
    --   We therefore need to /newtype/ the original Parser type, to allow it
    --   to have a different instance.
    newtype Parser t a = P (P.Parser t a)
    #ifdef __GLASGOW_HASKELL__
            deriving ((forall a b. (a -> b) -> Parser t a -> Parser t b)
    -> (forall a b. a -> Parser t b -> Parser t a)
    -> Functor (Parser t)
    forall a b. a -> Parser t b -> Parser t a
    forall a b. (a -> b) -> Parser t a -> Parser t b
    forall t a b. a -> Parser t b -> Parser t a
    forall t a b. (a -> b) -> Parser t a -> Parser t b
    forall (f :: * -> *).
    (forall a b. (a -> b) -> f a -> f b)
    -> (forall a b. a -> f b -> f a) -> Functor f
    $cfmap :: forall t a b. (a -> b) -> Parser t a -> Parser t b
    fmap :: forall a b. (a -> b) -> Parser t a -> Parser t b
    $c<$ :: forall t a b. a -> Parser t b -> Parser t a
    <$ :: forall a b. a -> Parser t b -> Parser t a
    Functor,Applicative (Parser t)
    Applicative (Parser t) =>
    (forall a b. Parser t a -> (a -> Parser t b) -> Parser t b)
    -> (forall a b. Parser t a -> Parser t b -> Parser t b)
    -> (forall a. a -> Parser t a)
    -> Monad (Parser t)
    forall t. Applicative (Parser t)
    forall a. a -> Parser t a
    forall t a. a -> Parser t a
    forall a b. Parser t a -> Parser t b -> Parser t b
    forall a b. Parser t a -> (a -> Parser t b) -> Parser t b
    forall t a b. Parser t a -> Parser t b -> Parser t b
    forall t a b. Parser t a -> (a -> Parser t b) -> Parser t b
    forall (m :: * -> *).
    Applicative m =>
    (forall a b. m a -> (a -> m b) -> m b)
    -> (forall a b. m a -> m b -> m b)
    -> (forall a. a -> m a)
    -> Monad m
    $c>>= :: forall t a b. Parser t a -> (a -> Parser t b) -> Parser t b
    >>= :: forall a b. Parser t a -> (a -> Parser t b) -> Parser t b
    $c>> :: forall t a b. Parser t a -> Parser t b -> Parser t b
    >> :: forall a b. Parser t a -> Parser t b -> Parser t b
    $creturn :: forall t a. a -> Parser t a
    return :: forall a. a -> Parser t a
    Monad,Monad (Parser t)
    Monad (Parser t) =>
    (forall a. String -> Parser t a) -> MonadFail (Parser t)
    forall t. Monad (Parser t)
    forall a. String -> Parser t a
    forall t a. String -> Parser t a
    forall (m :: * -> *).
    Monad m =>
    (forall a. String -> m a) -> MonadFail m
    $cfail :: forall t a. String -> Parser t a
    fail :: forall a. String -> Parser t a
    Fail.MonadFail,(forall a. Parser t a -> Parser t a)
    -> (forall a. Parser t a -> (String -> String) -> Parser t a)
    -> (forall a. [(String, Parser t a)] -> Parser t a)
    -> Commitment (Parser t)
    forall a. [(String, Parser t a)] -> Parser t a
    forall a. Parser t a -> Parser t a
    forall a. Parser t a -> (String -> String) -> Parser t a
    forall t a. [(String, Parser t a)] -> Parser t a
    forall t a. Parser t a -> Parser t a
    forall t a. Parser t a -> (String -> String) -> Parser t a
    forall (p :: * -> *).
    (forall a. p a -> p a)
    -> (forall a. p a -> (String -> String) -> p a)
    -> (forall a. [(String, p a)] -> p a)
    -> Commitment p
    $ccommit :: forall t a. Parser t a -> Parser t a
    commit :: forall a. Parser t a -> Parser t a
    $cadjustErr :: forall t a. Parser t a -> (String -> String) -> Parser t a
    adjustErr :: forall a. Parser t a -> (String -> String) -> Parser t a
    $coneOf' :: forall t a. [(String, Parser t a)] -> Parser t a
    oneOf' :: forall a. [(String, Parser t a)] -> Parser t a
    Commitment)
    #else
    instance Functor (Parser t) where
        fmap f (P p) = P (fmap f p)
    instance Monad (Parser t) where
        return x  = P (return x)
    #ifndef __MHS__
        fail      = Fail.fail
    #endif
        (P f) >>= g = P (f >>= (\(P g')->g') . g)
    instance Fail.MonadFail (Parser t) where
        fail e    = P (fail e)
    instance Commitment (Parser t) where
        commit (P p)   = P (commit p)
        (P p) `adjustErr` f  = P (p `adjustErr` f)
    #endif

    -- | Apply a parser to an input token sequence.
    runParser :: Parser t a -> [t] -> (a, [t])
    runParser :: forall t a. Parser t a -> [t] -> (a, [t])
    runParser (P (P.P [t] -> Result [t] a
    p)) = Result [t] a -> (a, [t])
    forall z a. Result z a -> (a, z)
    fromResult (Result [t] a -> (a, [t]))
    -> ([t] -> Result [t] a) -> [t] -> (a, [t])
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [t] -> Result [t] a
    p
      where
        fromResult :: Result z a -> (a, z)
        fromResult :: forall z a. Result z a -> (a, z)
    fromResult (Success z
    z a
    a)  =  (a
    a, z
    z)
        fromResult (Failure z
    z String
    e)  =  String -> (a, z)
    forall a. String -> a
    throwE String
    e
        fromResult (Committed Result z a
    r)  =  Result z a -> (a, z)
    forall z a. Result z a -> (a, z)
    fromResult Result z a
    r

    instance Applicative (Parser t) where
        pure :: forall a. a -> Parser t a
    pure a
    f    = a -> Parser t a
    forall a. a -> Parser t a
    forall (m :: * -> *) a. Monad m => a -> m a
    return a
    f
        --   Apply a parsed function to a parsed value.  This version
        --   is strict in the result of the function parser, but
        --   lazy in the result of the argument parser.  (Argument laziness is
        --   the distinctive feature over other implementations.)
        (P (P.P [t] -> Result [t] (a -> b)
    pf)) <*> :: forall a b. Parser t (a -> b) -> Parser t a -> Parser t b
    <*> Parser t a
    px = Parser t b -> Parser t b
    forall t a. Parser t a -> Parser t a
    P (([t] -> Result [t] b) -> Parser t b
    forall t a. ([t] -> Result [t] a) -> Parser t a
    P.P (Result [t] (a -> b) -> Result [t] b
    forall {a}. Result [t] (a -> a) -> Result [t] a
    continue (Result [t] (a -> b) -> Result [t] b)
    -> ([t] -> Result [t] (a -> b)) -> [t] -> Result [t] b
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [t] -> Result [t] (a -> b)
    pf))
          where
            continue :: Result [t] (a -> a) -> Result [t] a
    continue (Success [t]
    z a -> a
    f)  = let (a
    x,[t]
    z') = Parser t a -> [t] -> (a, [t])
    forall t a. Parser t a -> [t] -> (a, [t])
    runParser Parser t a
    px [t]
    z
                                      in [t] -> a -> Result [t] a
    forall z a. z -> a -> Result z a
    Success [t]
    z' (a -> a
    f a
    x)
            continue (Committed Result [t] (a -> a)
    r)  = Result [t] a -> Result [t] a
    forall z a. Result z a -> Result z a
    Committed (Result [t] (a -> a) -> Result [t] a
    continue Result [t] (a -> a)
    r)
            continue (Failure [t]
    z String
    e)  = [t] -> String -> Result [t] a
    forall z a. z -> String -> Result z a
    Failure [t]
    z String
    e
    #if defined(GLASGOW_HASKELL) && GLASGOW_HASKELL > 610
        p  <*  q  = p `discard` q
    #endif

    instance Alternative (Parser t) where
        empty :: forall a. Parser t a
    empty             = String -> Parser t a
    forall a. String -> Parser t a
    forall (m :: * -> *) a. MonadFail m => String -> m a
    fail String
    "no parse"
        (P Parser t a
    p) <|> :: forall a. Parser t a -> Parser t a -> Parser t a
    <|> (P Parser t a
    q)   = Parser t a -> Parser t a
    forall t a. Parser t a -> Parser t a
    P (Parser t a
    p Parser t a -> Parser t a -> Parser t a
    forall t a. Parser t a -> Parser t a -> Parser t a
    `P.onFail` Parser t a
    q)

    instance PolyParse (Parser t)

    ------------------------------------------------------------------------

    -- | Simply return the next token in the input tokenstream.
    next    ::  Parser t t
    next :: forall t. Parser t t
    next    = Parser t t -> Parser t t
    forall t a. Parser t a -> Parser t a
    P Parser t t
    forall t. Parser t t
    P.next

    -- | Succeed if the end of file/input has been reached, fail otherwise.
    eof     :: Parser t ()
    eof :: forall t. Parser t ()
    eof     = Parser t () -> Parser t ()
    forall t a. Parser t a -> Parser t a
    P Parser t ()
    forall t. Parser t ()
    P.eof

    -- | Return the next token if it satisfies the given predicate.
    satisfy :: (t->Bool) -> Parser t t
    satisfy :: forall t. (t -> Bool) -> Parser t t
    satisfy = Parser t t -> Parser t t
    forall t a. Parser t a -> Parser t a
    P (Parser t t -> Parser t t)
    -> ((t -> Bool) -> Parser t t) -> (t -> Bool) -> Parser t t
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (t -> Bool) -> Parser t t
    forall t. (t -> Bool) -> Parser t t
    P.satisfy

    -- | Return the next token if it satisfies the given predicate.  The String
    --   argument describes the predicate for better error messages.
    satisfyMsg :: Show t => (t->Bool) -> String -> Parser t t
    satisfyMsg :: forall t. Show t => (t -> Bool) -> String -> Parser t t
    satisfyMsg t -> Bool
    p String
    s = Parser t t -> Parser t t
    forall t a. Parser t a -> Parser t a
    P ((t -> Bool) -> String -> Parser t t
    forall t. Show t => (t -> Bool) -> String -> Parser t t
    P.satisfyMsg t -> Bool
    p String
    s)

    -- | @p `onFail` q@ means parse p, unless p fails, in which case
    --   parse q instead.
    --   Can be chained together to give multiple attempts to parse something.
    --   (Note that q could itself be a failing parser, e.g. to change the error
    --   message from that defined in p to something different.)
    --   However, a severe failure in p cannot be ignored.
    onFail  :: Parser t a -> Parser t a -> Parser t a
    onFail :: forall t a. Parser t a -> Parser t a -> Parser t a
    onFail (P Parser t a
    a) (P Parser t a
    b) = Parser t a -> Parser t a
    forall t a. Parser t a -> Parser t a
    P (Parser t a
    a Parser t a -> Parser t a -> Parser t a
    forall t a. Parser t a -> Parser t a -> Parser t a
    `P.onFail` Parser t a
    b)

    -- | Push some tokens back onto the front of the input stream and reparse.
    --   This is useful e.g. for recursively expanding macros.  When the
    --   user-parser recognises a macro use, it can lookup the macro
    --   expansion from the parse state, lex it, and then stuff the
    --   lexed expansion back down into the parser.
    reparse :: [t] -> Parser t ()
    reparse :: forall t. [t] -> Parser t ()
    reparse = Parser t () -> Parser t ()
    forall t a. Parser t a -> Parser t a
    P (Parser t () -> Parser t ())
    -> ([t] -> Parser t ()) -> [t] -> Parser t ()
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . [t] -> Parser t ()
    forall t. [t] -> Parser t ()
    P.reparse
    ------------------------------------------------------------------------