    {-# LANGUAGE MultiParamTypeClasses, TypeFamilies, FlexibleContexts #-}
    -- | Type classes to allow for XML handling functions to be generalized to
    -- work with different document types.
    module Text.XML.Expat.Internal.DocumentClass where

    import Text.XML.Expat.Internal.NodeClass (NodeClass)
    import Control.DeepSeq
    import Control.Monad (mzero)
    import Data.List.Class (List)

    -- | XML declaration, consisting of version, encoding and standalone.
    --
    -- The formatting functions always outputs only UTF-8, regardless
    -- of what encoding is specified here.  If you want to produce a document in a
    -- different encoding, then set the encoding here, format the document, and then
    -- convert the output text from UTF-8 to your desired encoding using some
    -- text conversion library.
    data XMLDeclaration text = XMLDeclaration text (Maybe text) (Maybe Bool) deriving (XMLDeclaration text -> XMLDeclaration text -> Bool
    (XMLDeclaration text -> XMLDeclaration text -> Bool)
    -> (XMLDeclaration text -> XMLDeclaration text -> Bool)
    -> Eq (XMLDeclaration text)
    forall text.
    Eq text =>
    XMLDeclaration text -> XMLDeclaration text -> Bool
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: forall text.
    Eq text =>
    XMLDeclaration text -> XMLDeclaration text -> Bool
    == :: XMLDeclaration text -> XMLDeclaration text -> Bool
    $c/= :: forall text.
    Eq text =>
    XMLDeclaration text -> XMLDeclaration text -> Bool
    /= :: XMLDeclaration text -> XMLDeclaration text -> Bool
    Eq, Int -> XMLDeclaration text -> ShowS
    [XMLDeclaration text] -> ShowS
    XMLDeclaration text -> String
    (Int -> XMLDeclaration text -> ShowS)
    -> (XMLDeclaration text -> String)
    -> ([XMLDeclaration text] -> ShowS)
    -> Show (XMLDeclaration text)
    forall text. Show text => Int -> XMLDeclaration text -> ShowS
    forall text. Show text => [XMLDeclaration text] -> ShowS
    forall text. Show text => XMLDeclaration text -> String
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: forall text. Show text => Int -> XMLDeclaration text -> ShowS
    showsPrec :: Int -> XMLDeclaration text -> ShowS
    $cshow :: forall text. Show text => XMLDeclaration text -> String
    show :: XMLDeclaration text -> String
    $cshowList :: forall text. Show text => [XMLDeclaration text] -> ShowS
    showList :: [XMLDeclaration text] -> ShowS
    Show)

    -- | Stub for future expansion.
    data DocumentTypeDeclaration (c :: * -> *) tag text = DocumentTypeDeclaration deriving (DocumentTypeDeclaration c tag text
    -> DocumentTypeDeclaration c tag text -> Bool
    (DocumentTypeDeclaration c tag text
     -> DocumentTypeDeclaration c tag text -> Bool)
    -> (DocumentTypeDeclaration c tag text
        -> DocumentTypeDeclaration c tag text -> Bool)
    -> Eq (DocumentTypeDeclaration c tag text)
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    forall (c :: * -> *) tag text.
    DocumentTypeDeclaration c tag text
    -> DocumentTypeDeclaration c tag text -> Bool
    $c== :: forall (c :: * -> *) tag text.
    DocumentTypeDeclaration c tag text
    -> DocumentTypeDeclaration c tag text -> Bool
    == :: DocumentTypeDeclaration c tag text
    -> DocumentTypeDeclaration c tag text -> Bool
    $c/= :: forall (c :: * -> *) tag text.
    DocumentTypeDeclaration c tag text
    -> DocumentTypeDeclaration c tag text -> Bool
    /= :: DocumentTypeDeclaration c tag text
    -> DocumentTypeDeclaration c tag text -> Bool
    Eq, Int -> DocumentTypeDeclaration c tag text -> ShowS
    [DocumentTypeDeclaration c tag text] -> ShowS
    DocumentTypeDeclaration c tag text -> String
    (Int -> DocumentTypeDeclaration c tag text -> ShowS)
    -> (DocumentTypeDeclaration c tag text -> String)
    -> ([DocumentTypeDeclaration c tag text] -> ShowS)
    -> Show (DocumentTypeDeclaration c tag text)
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    forall (c :: * -> *) tag text.
    Int -> DocumentTypeDeclaration c tag text -> ShowS
    forall (c :: * -> *) tag text.
    [DocumentTypeDeclaration c tag text] -> ShowS
    forall (c :: * -> *) tag text.
    DocumentTypeDeclaration c tag text -> String
    $cshowsPrec :: forall (c :: * -> *) tag text.
    Int -> DocumentTypeDeclaration c tag text -> ShowS
    showsPrec :: Int -> DocumentTypeDeclaration c tag text -> ShowS
    $cshow :: forall (c :: * -> *) tag text.
    DocumentTypeDeclaration c tag text -> String
    show :: DocumentTypeDeclaration c tag text -> String
    $cshowList :: forall (c :: * -> *) tag text.
    [DocumentTypeDeclaration c tag text] -> ShowS
    showList :: [DocumentTypeDeclaration c tag text] -> ShowS
    Show)

    data Misc text =
        Comment !text |
        ProcessingInstruction !text !text

    instance Show text => Show (Misc text) where
        showsPrec :: Int -> Misc text -> ShowS
    showsPrec Int
    d (ProcessingInstruction text
    t text
    txt) = Bool -> ShowS -> ShowS
    showParen (Int
    d Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    > Int
    10) (ShowS -> ShowS) -> ShowS -> ShowS
    forall a b. (a -> b) -> a -> b
    $
            (String
    "ProcessingInstruction "String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++) ShowS -> ShowS -> ShowS
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Int -> text -> ShowS
    forall a. Show a => Int -> a -> ShowS
    showsPrec Int
    11 text
    t ShowS -> ShowS -> ShowS
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . (String
    " "String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++) ShowS -> ShowS -> ShowS
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Int -> text -> ShowS
    forall a. Show a => Int -> a -> ShowS
    showsPrec Int
    11 text
    txt
        showsPrec Int
    d (Comment text
    t) = Bool -> ShowS -> ShowS
    showParen (Int
    d Int -> Int -> Bool
    forall a. Ord a => a -> a -> Bool
    > Int
    10) (ShowS -> ShowS) -> ShowS -> ShowS
    forall a b. (a -> b) -> a -> b
    $ (String
    "Comment "String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++) ShowS -> ShowS -> ShowS
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Int -> text -> ShowS
    forall a. Show a => Int -> a -> ShowS
    showsPrec Int
    11 text
    t

    instance Eq text => Eq (Misc text) where
        ProcessingInstruction text
    t1 text
    d1 == :: Misc text -> Misc text -> Bool
    == ProcessingInstruction text
    t2 text
    d2 =
            text
    t1 text -> text -> Bool
    forall a. Eq a => a -> a -> Bool
    == text
    t2 Bool -> Bool -> Bool
    &&
            text
    d1 text -> text -> Bool
    forall a. Eq a => a -> a -> Bool
    == text
    d2
        Comment text
    t1 == Comment text
    t2 = text
    t1 text -> text -> Bool
    forall a. Eq a => a -> a -> Bool
    == text
    t2
        Misc text
    _ == Misc text
    _ = Bool
    False

    instance NFData text => NFData (Misc text) where
        rnf :: Misc text -> ()
    rnf (ProcessingInstruction text
    target text
    txt) = (text, text) -> ()
    forall a. NFData a => a -> ()
    rnf (text
    target, text
    txt)
        rnf (Comment text
    txt) = text -> ()
    forall a. NFData a => a -> ()
    rnf text
    txt

    type family NodeType (d :: (* -> *) -> * -> * -> *) :: (* -> *) -> * -> * -> *

    class (Functor c, List c, NodeClass (NodeType d) c) => DocumentClass d (c :: * -> *) where
        -- | Get the XML declaration for this document.
        getXMLDeclaration :: d c tag text -> Maybe (XMLDeclaration text)

        -- | Get the Document Type Declaration (DTD) for this document.
        getDocumentTypeDeclaration :: d c tag text -> Maybe (DocumentTypeDeclaration c tag text)

        -- | Get the top-level 'Misc' nodes for this document.
        getTopLevelMiscs :: d c tag text -> c (Misc text)

        -- | Get the root element for this document.
        getRoot :: d c tag text -> NodeType d c tag text

        -- | Make a document with the specified fields.
        mkDocument :: Maybe (XMLDeclaration text)
                   -> Maybe (DocumentTypeDeclaration c tag text)
                   -> c (Misc text)
                   -> NodeType d c tag text
                   -> d c tag text

    -- | Make a document with the specified root node and all other information
    -- set to defaults.
    mkPlainDocument :: DocumentClass d c => NodeType d c tag text -> d c tag text
    mkPlainDocument :: forall (d :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
    DocumentClass d c =>
    NodeType d c tag text -> d c tag text
    mkPlainDocument = Maybe (XMLDeclaration text)
    -> Maybe (DocumentTypeDeclaration c tag text)
    -> c (Misc text)
    -> NodeType d c tag text
    -> d c tag text
    forall text tag.
    Maybe (XMLDeclaration text)
    -> Maybe (DocumentTypeDeclaration c tag text)
    -> c (Misc text)
    -> NodeType d c tag text
    -> d c tag text
    forall (d :: (* -> *) -> * -> * -> *) (c :: * -> *) text tag.
    DocumentClass d c =>
    Maybe (XMLDeclaration text)
    -> Maybe (DocumentTypeDeclaration c tag text)
    -> c (Misc text)
    -> NodeType d c tag text
    -> d c tag text
    mkDocument Maybe (XMLDeclaration text)
    forall a. Maybe a
    Nothing Maybe (DocumentTypeDeclaration c tag text)
    forall a. Maybe a
    Nothing c (Misc text)
    forall a. c a
    forall (m :: * -> *) a. MonadPlus m => m a
    mzero

    modifyXMLDeclaration :: DocumentClass d c =>
                            (Maybe (XMLDeclaration text) -> Maybe (XMLDeclaration text))
                         -> d c tag text
                         -> d c tag text
    modifyXMLDeclaration :: forall (d :: (* -> *) -> * -> * -> *) (c :: * -> *) text tag.
    DocumentClass d c =>
    (Maybe (XMLDeclaration text) -> Maybe (XMLDeclaration text))
    -> d c tag text -> d c tag text
    modifyXMLDeclaration Maybe (XMLDeclaration text) -> Maybe (XMLDeclaration text)
    f d c tag text
    doc = Maybe (XMLDeclaration text)
    -> Maybe (DocumentTypeDeclaration c tag text)
    -> c (Misc text)
    -> NodeType d c tag text
    -> d c tag text
    forall text tag.
    Maybe (XMLDeclaration text)
    -> Maybe (DocumentTypeDeclaration c tag text)
    -> c (Misc text)
    -> NodeType d c tag text
    -> d c tag text
    forall (d :: (* -> *) -> * -> * -> *) (c :: * -> *) text tag.
    DocumentClass d c =>
    Maybe (XMLDeclaration text)
    -> Maybe (DocumentTypeDeclaration c tag text)
    -> c (Misc text)
    -> NodeType d c tag text
    -> d c tag text
    mkDocument (Maybe (XMLDeclaration text) -> Maybe (XMLDeclaration text)
    f (Maybe (XMLDeclaration text) -> Maybe (XMLDeclaration text))
    -> Maybe (XMLDeclaration text) -> Maybe (XMLDeclaration text)
    forall a b. (a -> b) -> a -> b
    $ d c tag text -> Maybe (XMLDeclaration text)
    forall tag text. d c tag text -> Maybe (XMLDeclaration text)
    forall (d :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
    DocumentClass d c =>
    d c tag text -> Maybe (XMLDeclaration text)
    getXMLDeclaration d c tag text
    doc) (d c tag text -> Maybe (DocumentTypeDeclaration c tag text)
    forall tag text.
    d c tag text -> Maybe (DocumentTypeDeclaration c tag text)
    forall (d :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
    DocumentClass d c =>
    d c tag text -> Maybe (DocumentTypeDeclaration c tag text)
    getDocumentTypeDeclaration d c tag text
    doc)
            (d c tag text -> c (Misc text)
    forall tag text. d c tag text -> c (Misc text)
    forall (d :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
    DocumentClass d c =>
    d c tag text -> c (Misc text)
    getTopLevelMiscs d c tag text
    doc) (d c tag text -> NodeType d c tag text
    forall tag text. d c tag text -> NodeType d c tag text
    forall (d :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
    DocumentClass d c =>
    d c tag text -> NodeType d c tag text
    getRoot d c tag text
    doc)

    modifyDocumentTypeDeclaration :: DocumentClass d c =>
                                     (Maybe (DocumentTypeDeclaration c tag text) -> Maybe (DocumentTypeDeclaration c tag text))
                                  -> d c tag text
                                  -> d c tag text
    modifyDocumentTypeDeclaration :: forall (d :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
    DocumentClass d c =>
    (Maybe (DocumentTypeDeclaration c tag text)
     -> Maybe (DocumentTypeDeclaration c tag text))
    -> d c tag text -> d c tag text
    modifyDocumentTypeDeclaration Maybe (DocumentTypeDeclaration c tag text)
    -> Maybe (DocumentTypeDeclaration c tag text)
    f d c tag text
    doc = Maybe (XMLDeclaration text)
    -> Maybe (DocumentTypeDeclaration c tag text)
    -> c (Misc text)
    -> NodeType d c tag text
    -> d c tag text
    forall text tag.
    Maybe (XMLDeclaration text)
    -> Maybe (DocumentTypeDeclaration c tag text)
    -> c (Misc text)
    -> NodeType d c tag text
    -> d c tag text
    forall (d :: (* -> *) -> * -> * -> *) (c :: * -> *) text tag.
    DocumentClass d c =>
    Maybe (XMLDeclaration text)
    -> Maybe (DocumentTypeDeclaration c tag text)
    -> c (Misc text)
    -> NodeType d c tag text
    -> d c tag text
    mkDocument (d c tag text -> Maybe (XMLDeclaration text)
    forall tag text. d c tag text -> Maybe (XMLDeclaration text)
    forall (d :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
    DocumentClass d c =>
    d c tag text -> Maybe (XMLDeclaration text)
    getXMLDeclaration d c tag text
    doc) (Maybe (DocumentTypeDeclaration c tag text)
    -> Maybe (DocumentTypeDeclaration c tag text)
    f (Maybe (DocumentTypeDeclaration c tag text)
     -> Maybe (DocumentTypeDeclaration c tag text))
    -> Maybe (DocumentTypeDeclaration c tag text)
    -> Maybe (DocumentTypeDeclaration c tag text)
    forall a b. (a -> b) -> a -> b
    $ d c tag text -> Maybe (DocumentTypeDeclaration c tag text)
    forall tag text.
    d c tag text -> Maybe (DocumentTypeDeclaration c tag text)
    forall (d :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
    DocumentClass d c =>
    d c tag text -> Maybe (DocumentTypeDeclaration c tag text)
    getDocumentTypeDeclaration d c tag text
    doc)
            (d c tag text -> c (Misc text)
    forall tag text. d c tag text -> c (Misc text)
    forall (d :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
    DocumentClass d c =>
    d c tag text -> c (Misc text)
    getTopLevelMiscs d c tag text
    doc) (d c tag text -> NodeType d c tag text
    forall tag text. d c tag text -> NodeType d c tag text
    forall (d :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
    DocumentClass d c =>
    d c tag text -> NodeType d c tag text
    getRoot d c tag text
    doc)

    modifyTopLevelMiscs :: DocumentClass d c =>
                           (c (Misc text) -> c (Misc text))
                        -> d c tag text
                        -> d c tag text
    modifyTopLevelMiscs :: forall (d :: (* -> *) -> * -> * -> *) (c :: * -> *) text tag.
    DocumentClass d c =>
    (c (Misc text) -> c (Misc text)) -> d c tag text -> d c tag text
    modifyTopLevelMiscs c (Misc text) -> c (Misc text)
    f d c tag text
    doc = Maybe (XMLDeclaration text)
    -> Maybe (DocumentTypeDeclaration c tag text)
    -> c (Misc text)
    -> NodeType d c tag text
    -> d c tag text
    forall text tag.
    Maybe (XMLDeclaration text)
    -> Maybe (DocumentTypeDeclaration c tag text)
    -> c (Misc text)
    -> NodeType d c tag text
    -> d c tag text
    forall (d :: (* -> *) -> * -> * -> *) (c :: * -> *) text tag.
    DocumentClass d c =>
    Maybe (XMLDeclaration text)
    -> Maybe (DocumentTypeDeclaration c tag text)
    -> c (Misc text)
    -> NodeType d c tag text
    -> d c tag text
    mkDocument (d c tag text -> Maybe (XMLDeclaration text)
    forall tag text. d c tag text -> Maybe (XMLDeclaration text)
    forall (d :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
    DocumentClass d c =>
    d c tag text -> Maybe (XMLDeclaration text)
    getXMLDeclaration d c tag text
    doc) (d c tag text -> Maybe (DocumentTypeDeclaration c tag text)
    forall tag text.
    d c tag text -> Maybe (DocumentTypeDeclaration c tag text)
    forall (d :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
    DocumentClass d c =>
    d c tag text -> Maybe (DocumentTypeDeclaration c tag text)
    getDocumentTypeDeclaration d c tag text
    doc)
            (c (Misc text) -> c (Misc text)
    f (c (Misc text) -> c (Misc text)) -> c (Misc text) -> c (Misc text)
    forall a b. (a -> b) -> a -> b
    $ d c tag text -> c (Misc text)
    forall tag text. d c tag text -> c (Misc text)
    forall (d :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
    DocumentClass d c =>
    d c tag text -> c (Misc text)
    getTopLevelMiscs d c tag text
    doc) (d c tag text -> NodeType d c tag text
    forall tag text. d c tag text -> NodeType d c tag text
    forall (d :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
    DocumentClass d c =>
    d c tag text -> NodeType d c tag text
    getRoot d c tag text
    doc)

    modifyRoot :: DocumentClass d c =>
                  (NodeType d c tag text -> NodeType d c tag text)
               -> d c tag text
               -> d c tag text
    modifyRoot :: forall (d :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
    DocumentClass d c =>
    (NodeType d c tag text -> NodeType d c tag text)
    -> d c tag text -> d c tag text
    modifyRoot NodeType d c tag text -> NodeType d c tag text
    f d c tag text
    doc = Maybe (XMLDeclaration text)
    -> Maybe (DocumentTypeDeclaration c tag text)
    -> c (Misc text)
    -> NodeType d c tag text
    -> d c tag text
    forall text tag.
    Maybe (XMLDeclaration text)
    -> Maybe (DocumentTypeDeclaration c tag text)
    -> c (Misc text)
    -> NodeType d c tag text
    -> d c tag text
    forall (d :: (* -> *) -> * -> * -> *) (c :: * -> *) text tag.
    DocumentClass d c =>
    Maybe (XMLDeclaration text)
    -> Maybe (DocumentTypeDeclaration c tag text)
    -> c (Misc text)
    -> NodeType d c tag text
    -> d c tag text
    mkDocument (d c tag text -> Maybe (XMLDeclaration text)
    forall tag text. d c tag text -> Maybe (XMLDeclaration text)
    forall (d :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
    DocumentClass d c =>
    d c tag text -> Maybe (XMLDeclaration text)
    getXMLDeclaration d c tag text
    doc) (d c tag text -> Maybe (DocumentTypeDeclaration c tag text)
    forall tag text.
    d c tag text -> Maybe (DocumentTypeDeclaration c tag text)
    forall (d :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
    DocumentClass d c =>
    d c tag text -> Maybe (DocumentTypeDeclaration c tag text)
    getDocumentTypeDeclaration d c tag text
    doc)
            (d c tag text -> c (Misc text)
    forall tag text. d c tag text -> c (Misc text)
    forall (d :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
    DocumentClass d c =>
    d c tag text -> c (Misc text)
    getTopLevelMiscs d c tag text
    doc) (NodeType d c tag text -> NodeType d c tag text
    f (NodeType d c tag text -> NodeType d c tag text)
    -> NodeType d c tag text -> NodeType d c tag text
    forall a b. (a -> b) -> a -> b
    $ d c tag text -> NodeType d c tag text
    forall tag text. d c tag text -> NodeType d c tag text
    forall (d :: (* -> *) -> * -> * -> *) (c :: * -> *) tag text.
    DocumentClass d c =>
    d c tag text -> NodeType d c tag text
    getRoot d c tag text
    doc)