    {-# LANGUAGE DeriveDataTypeable, FlexibleInstances #-}

    -- |
    -- Module:      Data.Configurator.Types.Internal
    -- Copyright:   (c) 2011 MailRank, Inc.
    -- License:     BSD3
    -- Maintainer:  Bryan O'Sullivan <bos@serpentine.com>
    -- Stability:   experimental
    -- Portability: portable
    --
    -- Types for working with configuration files.

    module Data.Configurator.Types.Internal
        (
          BaseConfig(..)
        , Config(..)
        , Configured(..)
        , AutoConfig(..)
        , Worth(..)
        , Name
        , Value(..)
        , Binding
        , Path
        , Directive(..)
        , ConfigError(..)
        , KeyError(..)
        , Interpolate(..)
        , Pattern(..)
        , exact
        , prefix
        , ChangeHandler
        ) where

    import Control.Exception
    import Data.Data (Data)
    import Data.Hashable (Hashable(..))
    import Data.IORef (IORef)
    import Data.List (isSuffixOf)
    import Data.String (IsString(..))
    import Data.Text (Text)
    import qualified Data.Text as T
    import Data.Typeable (Typeable)
    import Prelude hiding (lookup)
    import qualified Data.HashMap.Lazy as H

    data Worth a = Required { forall a. Worth a -> a
    worth :: a }
                 | Optional { worth :: a }
                   deriving (Int -> Worth a -> ShowS
    [Worth a] -> ShowS
    Worth a -> String
    (Int -> Worth a -> ShowS)
    -> (Worth a -> String) -> ([Worth a] -> ShowS) -> Show (Worth a)
    forall a. Show a => Int -> Worth a -> ShowS
    forall a. Show a => [Worth a] -> ShowS
    forall a. Show a => Worth a -> String
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: forall a. Show a => Int -> Worth a -> ShowS
    showsPrec :: Int -> Worth a -> ShowS
    $cshow :: forall a. Show a => Worth a -> String
    show :: Worth a -> String
    $cshowList :: forall a. Show a => [Worth a] -> ShowS
    showList :: [Worth a] -> ShowS
    Show, Typeable)

    instance IsString (Worth FilePath) where
        fromString :: String -> Worth String
    fromString = String -> Worth String
    forall a. a -> Worth a
    Required

    instance (Eq a) => Eq (Worth a) where
        Worth a
    a == :: Worth a -> Worth a -> Bool
    == Worth a
    b = Worth a -> a
    forall a. Worth a -> a
    worth Worth a
    a a -> a -> Bool
    forall a. Eq a => a -> a -> Bool
    == Worth a -> a
    forall a. Worth a -> a
    worth Worth a
    b

    instance (Hashable a) => Hashable (Worth a) where
        hashWithSalt :: Int -> Worth a -> Int
    hashWithSalt Int
    salt Worth a
    v = Int -> a -> Int
    forall a. Hashable a => Int -> a -> Int
    hashWithSalt Int
    salt (Worth a -> a
    forall a. Worth a -> a
    worth Worth a
    v)

    -- | Global configuration data.  This is the top-level config from which
    -- 'Config' values are derived by choosing a root location.
    data BaseConfig = BaseConfig {
          BaseConfig -> Maybe AutoConfig
    cfgAuto :: Maybe AutoConfig
        , BaseConfig -> IORef [(Name, Worth Name)]
    cfgPaths :: IORef [(Name, Worth Path)]
        -- ^ The files from which the 'Config' was loaded.
        , BaseConfig -> IORef (HashMap Name Value)
    cfgMap :: IORef (H.HashMap Name Value)
        , BaseConfig -> IORef (HashMap Pattern [ChangeHandler])
    cfgSubs :: IORef (H.HashMap Pattern [ChangeHandler])
        }

    -- | Configuration data.
    data Config = Config { Config -> Name
    root :: Text, Config -> BaseConfig
    baseCfg :: BaseConfig }

    instance Functor Worth where
        fmap :: forall a b. (a -> b) -> Worth a -> Worth b
    fmap a -> b
    f (Required a
    a) = b -> Worth b
    forall a. a -> Worth a
    Required (a -> b
    f a
    a)
        fmap a -> b
    f (Optional a
    a) = b -> Worth b
    forall a. a -> Worth a
    Optional (a -> b
    f a
    a)

    -- | An action to be invoked if a configuration property is changed.
    --
    -- If this action is invoked and throws an exception, the 'onError'
    -- function will be called.
    type ChangeHandler = Name
                       -- ^ Name of the changed property.
                       -> Maybe Value
                       -- ^ Its new value, or 'Nothing' if it has
                       -- vanished.
                       -> IO ()

    -- | A pattern specifying the name of a property that has changed.
    --
    -- This type is an instance of the 'IsString' class.  If you use the
    -- @OverloadedStrings@ language extension and want to write a
    -- 'prefix'-matching pattern as a literal string, do so by suffixing
    -- it with \"@.*@\", for example as follows:
    --
    -- > "foo.*"
    --
    -- If a pattern written as a literal string does not end with
    -- \"@.*@\", it is assumed to be 'exact'.
    data Pattern = Exact Name
                 -- ^ An exact match.
                 | Prefix Name
                 -- ^ A prefix match.  Given @'Prefix' \"foo\"@, this will
                 -- match @\"foo.bar\"@, but not @\"foo\"@ or
                 -- @\"foobar\"@.
                   deriving (Pattern -> Pattern -> Bool
    (Pattern -> Pattern -> Bool)
    -> (Pattern -> Pattern -> Bool) -> Eq Pattern
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: Pattern -> Pattern -> Bool
    == :: Pattern -> Pattern -> Bool
    $c/= :: Pattern -> Pattern -> Bool
    /= :: Pattern -> Pattern -> Bool
    Eq, Int -> Pattern -> ShowS
    [Pattern] -> ShowS
    Pattern -> String
    (Int -> Pattern -> ShowS)
    -> (Pattern -> String) -> ([Pattern] -> ShowS) -> Show Pattern
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> Pattern -> ShowS
    showsPrec :: Int -> Pattern -> ShowS
    $cshow :: Pattern -> String
    show :: Pattern -> String
    $cshowList :: [Pattern] -> ShowS
    showList :: [Pattern] -> ShowS
    Show, Typeable, Typeable Pattern
    Typeable Pattern =>
    (forall (c :: * -> *).
     (forall d b. Data d => c (d -> b) -> d -> c b)
     -> (forall g. g -> c g) -> Pattern -> c Pattern)
    -> (forall (c :: * -> *).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c Pattern)
    -> (Pattern -> Constr)
    -> (Pattern -> DataType)
    -> (forall (t :: * -> *) (c :: * -> *).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c Pattern))
    -> (forall (t :: * -> * -> *) (c :: * -> *).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Pattern))
    -> ((forall b. Data b => b -> b) -> Pattern -> Pattern)
    -> (forall r r'.
        (r -> r' -> r)
        -> r -> (forall d. Data d => d -> r') -> Pattern -> r)
    -> (forall r r'.
        (r' -> r -> r)
        -> r -> (forall d. Data d => d -> r') -> Pattern -> r)
    -> (forall u. (forall d. Data d => d -> u) -> Pattern -> [u])
    -> (forall u. Int -> (forall d. Data d => d -> u) -> Pattern -> u)
    -> (forall (m :: * -> *).
        Monad m =>
        (forall d. Data d => d -> m d) -> Pattern -> m Pattern)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> Pattern -> m Pattern)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> Pattern -> m Pattern)
    -> Data Pattern
    Pattern -> Constr
    Pattern -> DataType
    (forall b. Data b => b -> b) -> Pattern -> Pattern
    forall a.
    Typeable a =>
    (forall (c :: * -> *).
     (forall d b. Data d => c (d -> b) -> d -> c b)
     -> (forall g. g -> c g) -> a -> c a)
    -> (forall (c :: * -> *).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c a)
    -> (a -> Constr)
    -> (a -> DataType)
    -> (forall (t :: * -> *) (c :: * -> *).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c a))
    -> (forall (t :: * -> * -> *) (c :: * -> *).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
    -> ((forall b. Data b => b -> b) -> a -> a)
    -> (forall r r'.
        (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
    -> (forall r r'.
        (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
    -> (forall u. (forall d. Data d => d -> u) -> a -> [u])
    -> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
    -> (forall (m :: * -> *).
        Monad m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> Data a
    forall u. Int -> (forall d. Data d => d -> u) -> Pattern -> u
    forall u. (forall d. Data d => d -> u) -> Pattern -> [u]
    forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> Pattern -> r
    forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> Pattern -> r
    forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> Pattern -> m Pattern
    forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Pattern -> m Pattern
    forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c Pattern
    forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Pattern -> c Pattern
    forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c Pattern)
    forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Pattern)
    $cgfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Pattern -> c Pattern
    gfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Pattern -> c Pattern
    $cgunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c Pattern
    gunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c Pattern
    $ctoConstr :: Pattern -> Constr
    toConstr :: Pattern -> Constr
    $cdataTypeOf :: Pattern -> DataType
    dataTypeOf :: Pattern -> DataType
    $cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c Pattern)
    dataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c Pattern)
    $cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Pattern)
    dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Pattern)
    $cgmapT :: (forall b. Data b => b -> b) -> Pattern -> Pattern
    gmapT :: (forall b. Data b => b -> b) -> Pattern -> Pattern
    $cgmapQl :: forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> Pattern -> r
    gmapQl :: forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> Pattern -> r
    $cgmapQr :: forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> Pattern -> r
    gmapQr :: forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> Pattern -> r
    $cgmapQ :: forall u. (forall d. Data d => d -> u) -> Pattern -> [u]
    gmapQ :: forall u. (forall d. Data d => d -> u) -> Pattern -> [u]
    $cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Pattern -> u
    gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Pattern -> u
    $cgmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> Pattern -> m Pattern
    gmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> Pattern -> m Pattern
    $cgmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Pattern -> m Pattern
    gmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Pattern -> m Pattern
    $cgmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Pattern -> m Pattern
    gmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Pattern -> m Pattern
    Data)

    -- | A pattern that must match exactly.
    exact :: Text -> Pattern
    exact :: Name -> Pattern
    exact = Name -> Pattern
    Exact

    -- | A pattern that matches on a prefix of a property name.  Given
    -- @\"foo\"@, this will match @\"foo.bar\"@, but not @\"foo\"@ or
    -- @\"foobar\"@.
    prefix :: Text -> Pattern
    prefix :: Name -> Pattern
    prefix Name
    p = Name -> Pattern
    Prefix (Name
    p Name -> Char -> Name
    `T.snoc` Char
    '.')

    instance IsString Pattern where
        fromString :: String -> Pattern
    fromString String
    s
            | String
    ".*" String -> String -> Bool
    forall a. Eq a => [a] -> [a] -> Bool
    `isSuffixOf` String
    s = Name -> Pattern
    Prefix (Name -> Pattern) -> (String -> Name) -> String -> Pattern
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . HasCallStack => Name -> Name
    Name -> Name
    T.init (Name -> Name) -> (String -> Name) -> String -> Name
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . String -> Name
    T.pack (String -> Pattern) -> String -> Pattern
    forall a b. (a -> b) -> a -> b
    $ String
    s
            | Bool
    otherwise           = Name -> Pattern
    Exact (String -> Name
    T.pack String
    s)

    instance Hashable Pattern where
        hashWithSalt :: Int -> Pattern -> Int
    hashWithSalt Int
    salt (Exact Name
    n)  = Int -> Name -> Int
    forall a. Hashable a => Int -> a -> Int
    hashWithSalt Int
    salt Name
    n
        hashWithSalt Int
    salt (Prefix Name
    n) = Int -> Name -> Int
    forall a. Hashable a => Int -> a -> Int
    hashWithSalt Int
    salt Name
    n

    -- | This class represents types that can be automatically and safely
    -- converted /from/ a 'Value' /to/ a destination type.  If conversion
    -- fails because the types are not compatible, 'Nothing' is returned.
    --
    -- For an example of compatibility, a 'Value' of 'Bool' 'True' cannot
    -- be 'convert'ed to an 'Int'.
    class Configured a where
        convert :: Value -> Maybe a

        convertList :: Value -> Maybe [a]
        convertList (List [Value]
    xs) = (Value -> Maybe a) -> [Value] -> Maybe [a]
    forall (t :: * -> *) (m :: * -> *) a b.
    (Traversable t, Monad m) =>
    (a -> m b) -> t a -> m (t b)
    forall (m :: * -> *) a b. Monad m => (a -> m b) -> [a] -> m [b]
    mapM Value -> Maybe a
    forall a. Configured a => Value -> Maybe a
    convert [Value]
    xs
        convertList Value
    _         = Maybe [a]
    forall a. Maybe a
    Nothing

    instance Configured a => Configured [a] where
        convert :: Value -> Maybe [a]
    convert = Value -> Maybe [a]
    forall a. Configured a => Value -> Maybe [a]
    convertList

    -- | An error occurred while processing a configuration file.
    data ConfigError = ParseError FilePath String
                       deriving (Int -> ConfigError -> ShowS
    [ConfigError] -> ShowS
    ConfigError -> String
    (Int -> ConfigError -> ShowS)
    -> (ConfigError -> String)
    -> ([ConfigError] -> ShowS)
    -> Show ConfigError
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> ConfigError -> ShowS
    showsPrec :: Int -> ConfigError -> ShowS
    $cshow :: ConfigError -> String
    show :: ConfigError -> String
    $cshowList :: [ConfigError] -> ShowS
    showList :: [ConfigError] -> ShowS
    Show, Typeable)

    instance Exception ConfigError

    -- | An error occurred while lookup up the given 'Name'.
    data KeyError = KeyError Name
                  deriving (Int -> KeyError -> ShowS
    [KeyError] -> ShowS
    KeyError -> String
    (Int -> KeyError -> ShowS)
    -> (KeyError -> String) -> ([KeyError] -> ShowS) -> Show KeyError
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> KeyError -> ShowS
    showsPrec :: Int -> KeyError -> ShowS
    $cshow :: KeyError -> String
    show :: KeyError -> String
    $cshowList :: [KeyError] -> ShowS
    showList :: [KeyError] -> ShowS
    Show, Typeable)

    instance Exception KeyError

    -- | Directions for automatically reloading 'Config' data.
    data AutoConfig = AutoConfig {
          AutoConfig -> Int
    interval :: Int
        -- ^ Interval (in seconds) at which to check for updates to config
        -- files.  The smallest allowed interval is one second.
        , AutoConfig -> SomeException -> IO ()
    onError :: SomeException -> IO ()
        -- ^ Action invoked when an attempt to reload a 'Config' or notify
        -- a 'ChangeHandler' causes an exception to be thrown.
        --
        -- If this action rethrows its exception or throws a new
        -- exception, the modification checking thread will be killed.
        -- You may want your application to treat that as a fatal error,
        -- as its configuration may no longer be consistent.
        } deriving (Typeable)

    instance Show AutoConfig where
        show :: AutoConfig -> String
    show AutoConfig
    c = String
    "AutoConfig {interval = " String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ Int -> String
    forall a. Show a => a -> String
    show (AutoConfig -> Int
    interval AutoConfig
    c) String -> ShowS
    forall a. [a] -> [a] -> [a]
    ++ String
    "}"

    -- | The name of a 'Config' value.
    type Name = Text

    -- | A packed 'FilePath'.
    type Path = Text

    -- | A name-value binding.
    type Binding = (Name,Value)

    -- | A directive in a configuration file.
    data Directive = Import Path
                   | Bind Name Value
                   | Group Name [Directive]
                     deriving (Directive -> Directive -> Bool
    (Directive -> Directive -> Bool)
    -> (Directive -> Directive -> Bool) -> Eq Directive
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: Directive -> Directive -> Bool
    == :: Directive -> Directive -> Bool
    $c/= :: Directive -> Directive -> Bool
    /= :: Directive -> Directive -> Bool
    Eq, Int -> Directive -> ShowS
    [Directive] -> ShowS
    Directive -> String
    (Int -> Directive -> ShowS)
    -> (Directive -> String)
    -> ([Directive] -> ShowS)
    -> Show Directive
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> Directive -> ShowS
    showsPrec :: Int -> Directive -> ShowS
    $cshow :: Directive -> String
    show :: Directive -> String
    $cshowList :: [Directive] -> ShowS
    showList :: [Directive] -> ShowS
    Show, Typeable, Typeable Directive
    Typeable Directive =>
    (forall (c :: * -> *).
     (forall d b. Data d => c (d -> b) -> d -> c b)
     -> (forall g. g -> c g) -> Directive -> c Directive)
    -> (forall (c :: * -> *).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c Directive)
    -> (Directive -> Constr)
    -> (Directive -> DataType)
    -> (forall (t :: * -> *) (c :: * -> *).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c Directive))
    -> (forall (t :: * -> * -> *) (c :: * -> *).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Directive))
    -> ((forall b. Data b => b -> b) -> Directive -> Directive)
    -> (forall r r'.
        (r -> r' -> r)
        -> r -> (forall d. Data d => d -> r') -> Directive -> r)
    -> (forall r r'.
        (r' -> r -> r)
        -> r -> (forall d. Data d => d -> r') -> Directive -> r)
    -> (forall u. (forall d. Data d => d -> u) -> Directive -> [u])
    -> (forall u.
        Int -> (forall d. Data d => d -> u) -> Directive -> u)
    -> (forall (m :: * -> *).
        Monad m =>
        (forall d. Data d => d -> m d) -> Directive -> m Directive)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> Directive -> m Directive)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> Directive -> m Directive)
    -> Data Directive
    Directive -> Constr
    Directive -> DataType
    (forall b. Data b => b -> b) -> Directive -> Directive
    forall a.
    Typeable a =>
    (forall (c :: * -> *).
     (forall d b. Data d => c (d -> b) -> d -> c b)
     -> (forall g. g -> c g) -> a -> c a)
    -> (forall (c :: * -> *).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c a)
    -> (a -> Constr)
    -> (a -> DataType)
    -> (forall (t :: * -> *) (c :: * -> *).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c a))
    -> (forall (t :: * -> * -> *) (c :: * -> *).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
    -> ((forall b. Data b => b -> b) -> a -> a)
    -> (forall r r'.
        (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
    -> (forall r r'.
        (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
    -> (forall u. (forall d. Data d => d -> u) -> a -> [u])
    -> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
    -> (forall (m :: * -> *).
        Monad m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> Data a
    forall u. Int -> (forall d. Data d => d -> u) -> Directive -> u
    forall u. (forall d. Data d => d -> u) -> Directive -> [u]
    forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> Directive -> r
    forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> Directive -> r
    forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> Directive -> m Directive
    forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Directive -> m Directive
    forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c Directive
    forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Directive -> c Directive
    forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c Directive)
    forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Directive)
    $cgfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Directive -> c Directive
    gfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Directive -> c Directive
    $cgunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c Directive
    gunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c Directive
    $ctoConstr :: Directive -> Constr
    toConstr :: Directive -> Constr
    $cdataTypeOf :: Directive -> DataType
    dataTypeOf :: Directive -> DataType
    $cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c Directive)
    dataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c Directive)
    $cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Directive)
    dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Directive)
    $cgmapT :: (forall b. Data b => b -> b) -> Directive -> Directive
    gmapT :: (forall b. Data b => b -> b) -> Directive -> Directive
    $cgmapQl :: forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> Directive -> r
    gmapQl :: forall r r'.
    (r -> r' -> r)
    -> r -> (forall d. Data d => d -> r') -> Directive -> r
    $cgmapQr :: forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> Directive -> r
    gmapQr :: forall r r'.
    (r' -> r -> r)
    -> r -> (forall d. Data d => d -> r') -> Directive -> r
    $cgmapQ :: forall u. (forall d. Data d => d -> u) -> Directive -> [u]
    gmapQ :: forall u. (forall d. Data d => d -> u) -> Directive -> [u]
    $cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Directive -> u
    gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Directive -> u
    $cgmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> Directive -> m Directive
    gmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> Directive -> m Directive
    $cgmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Directive -> m Directive
    gmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Directive -> m Directive
    $cgmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Directive -> m Directive
    gmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Directive -> m Directive
    Data)

    -- | A value in a 'Config'.
    data Value = Bool Bool
               -- ^ A Boolean. Represented in a configuration file as @on@
               -- or @off@, @true@ or @false@ (case sensitive).
               | String Text
               -- ^ A Unicode string.  Represented in a configuration file
               -- as text surrounded by double quotes.
               --
               -- Escape sequences:
               --
               -- * @\\n@ - newline
               --
               -- * @\\r@ - carriage return
               --
               -- * @\\t@ - horizontal tab
               --
               -- * @\\\\@ - backslash
               --
               -- * @\\\"@ - quotes
               --
               -- * @\\u@/xxxx/ - Unicode character, encoded as four
               --   hexadecimal digits
               --
               -- * @\\u@/xxxx/@\\u@/xxxx/ - Unicode character (as two
               --   UTF-16 surrogates)
               | Number Rational
               -- ^ Integer.
               | List [Value]
               -- ^ Heterogeneous list.  Represented in a configuration
               -- file as an opening square bracket \"@[@\", followed by a
               -- comma-separated series of values, ending with a closing
               -- square bracket \"@]@\".
                 deriving (Value -> Value -> Bool
    (Value -> Value -> Bool) -> (Value -> Value -> Bool) -> Eq Value
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: Value -> Value -> Bool
    == :: Value -> Value -> Bool
    $c/= :: Value -> Value -> Bool
    /= :: Value -> Value -> Bool
    Eq, Int -> Value -> ShowS
    [Value] -> ShowS
    Value -> String
    (Int -> Value -> ShowS)
    -> (Value -> String) -> ([Value] -> ShowS) -> Show Value
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> Value -> ShowS
    showsPrec :: Int -> Value -> ShowS
    $cshow :: Value -> String
    show :: Value -> String
    $cshowList :: [Value] -> ShowS
    showList :: [Value] -> ShowS
    Show, Typeable, Typeable Value
    Typeable Value =>
    (forall (c :: * -> *).
     (forall d b. Data d => c (d -> b) -> d -> c b)
     -> (forall g. g -> c g) -> Value -> c Value)
    -> (forall (c :: * -> *).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c Value)
    -> (Value -> Constr)
    -> (Value -> DataType)
    -> (forall (t :: * -> *) (c :: * -> *).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c Value))
    -> (forall (t :: * -> * -> *) (c :: * -> *).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Value))
    -> ((forall b. Data b => b -> b) -> Value -> Value)
    -> (forall r r'.
        (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Value -> r)
    -> (forall r r'.
        (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Value -> r)
    -> (forall u. (forall d. Data d => d -> u) -> Value -> [u])
    -> (forall u. Int -> (forall d. Data d => d -> u) -> Value -> u)
    -> (forall (m :: * -> *).
        Monad m =>
        (forall d. Data d => d -> m d) -> Value -> m Value)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> Value -> m Value)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> Value -> m Value)
    -> Data Value
    Value -> Constr
    Value -> DataType
    (forall b. Data b => b -> b) -> Value -> Value
    forall a.
    Typeable a =>
    (forall (c :: * -> *).
     (forall d b. Data d => c (d -> b) -> d -> c b)
     -> (forall g. g -> c g) -> a -> c a)
    -> (forall (c :: * -> *).
        (forall b r. Data b => c (b -> r) -> c r)
        -> (forall r. r -> c r) -> Constr -> c a)
    -> (a -> Constr)
    -> (a -> DataType)
    -> (forall (t :: * -> *) (c :: * -> *).
        Typeable t =>
        (forall d. Data d => c (t d)) -> Maybe (c a))
    -> (forall (t :: * -> * -> *) (c :: * -> *).
        Typeable t =>
        (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c a))
    -> ((forall b. Data b => b -> b) -> a -> a)
    -> (forall r r'.
        (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
    -> (forall r r'.
        (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> a -> r)
    -> (forall u. (forall d. Data d => d -> u) -> a -> [u])
    -> (forall u. Int -> (forall d. Data d => d -> u) -> a -> u)
    -> (forall (m :: * -> *).
        Monad m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> (forall (m :: * -> *).
        MonadPlus m =>
        (forall d. Data d => d -> m d) -> a -> m a)
    -> Data a
    forall u. Int -> (forall d. Data d => d -> u) -> Value -> u
    forall u. (forall d. Data d => d -> u) -> Value -> [u]
    forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Value -> r
    forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Value -> r
    forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> Value -> m Value
    forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Value -> m Value
    forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c Value
    forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Value -> c Value
    forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c Value)
    forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Value)
    $cgfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Value -> c Value
    gfoldl :: forall (c :: * -> *).
    (forall d b. Data d => c (d -> b) -> d -> c b)
    -> (forall g. g -> c g) -> Value -> c Value
    $cgunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c Value
    gunfold :: forall (c :: * -> *).
    (forall b r. Data b => c (b -> r) -> c r)
    -> (forall r. r -> c r) -> Constr -> c Value
    $ctoConstr :: Value -> Constr
    toConstr :: Value -> Constr
    $cdataTypeOf :: Value -> DataType
    dataTypeOf :: Value -> DataType
    $cdataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c Value)
    dataCast1 :: forall (t :: * -> *) (c :: * -> *).
    Typeable t =>
    (forall d. Data d => c (t d)) -> Maybe (c Value)
    $cdataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Value)
    dataCast2 :: forall (t :: * -> * -> *) (c :: * -> *).
    Typeable t =>
    (forall d e. (Data d, Data e) => c (t d e)) -> Maybe (c Value)
    $cgmapT :: (forall b. Data b => b -> b) -> Value -> Value
    gmapT :: (forall b. Data b => b -> b) -> Value -> Value
    $cgmapQl :: forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Value -> r
    gmapQl :: forall r r'.
    (r -> r' -> r) -> r -> (forall d. Data d => d -> r') -> Value -> r
    $cgmapQr :: forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Value -> r
    gmapQr :: forall r r'.
    (r' -> r -> r) -> r -> (forall d. Data d => d -> r') -> Value -> r
    $cgmapQ :: forall u. (forall d. Data d => d -> u) -> Value -> [u]
    gmapQ :: forall u. (forall d. Data d => d -> u) -> Value -> [u]
    $cgmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Value -> u
    gmapQi :: forall u. Int -> (forall d. Data d => d -> u) -> Value -> u
    $cgmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> Value -> m Value
    gmapM :: forall (m :: * -> *).
    Monad m =>
    (forall d. Data d => d -> m d) -> Value -> m Value
    $cgmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Value -> m Value
    gmapMp :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Value -> m Value
    $cgmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Value -> m Value
    gmapMo :: forall (m :: * -> *).
    MonadPlus m =>
    (forall d. Data d => d -> m d) -> Value -> m Value
    Data)

    -- | An interpolation directive.
    data Interpolate = Literal Text
                     | Interpolate Text
                       deriving (Interpolate -> Interpolate -> Bool
    (Interpolate -> Interpolate -> Bool)
    -> (Interpolate -> Interpolate -> Bool) -> Eq Interpolate
    forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
    $c== :: Interpolate -> Interpolate -> Bool
    == :: Interpolate -> Interpolate -> Bool
    $c/= :: Interpolate -> Interpolate -> Bool
    /= :: Interpolate -> Interpolate -> Bool
    Eq, Int -> Interpolate -> ShowS
    [Interpolate] -> ShowS
    Interpolate -> String
    (Int -> Interpolate -> ShowS)
    -> (Interpolate -> String)
    -> ([Interpolate] -> ShowS)
    -> Show Interpolate
    forall a.
    (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
    $cshowsPrec :: Int -> Interpolate -> ShowS
    showsPrec :: Int -> Interpolate -> ShowS
    $cshow :: Interpolate -> String
    show :: Interpolate -> String
    $cshowList :: [Interpolate] -> ShowS
    showList :: [Interpolate] -> ShowS
    Show)