    -- |
    -- Module      : Language.Haskell.TH.Lib.Extra
    -- Copyright   : 2013 Kei Hibino
    -- License     : BSD3
    --
    -- Maintainer  : ex8k.hibino@gmail.com
    -- Stability   : experimental
    -- Portability : unknown
    --
    -- This module provides extra helper functions
    -- complementing "Language.Haskell.TH.Lib"
    module Language.Haskell.TH.Lib.Extra (
      -- * Extra template functions
      -- $extraTemplateFunctions
      integralE, simpleValD, maybeD,

      -- * Pretty printing for 'Q' monad
      -- $prettyPrint
      pprQ,

      -- * Functions to print message or errors when compile time
      -- $compileMessage
      reportWarning, reportError,
      ) where

    import Language.Haskell.TH
      (Ppr, ppr, Q, runQ,
       Name, Dec, sigD, valD, TypeQ, varP, normalB,
       ExpQ, litE, integerL)
    import Language.Haskell.TH.PprLib (Doc)
    import Language.Haskell.TH.Syntax (Quasi, qReport)

    {- $extraTemplateFunctions
    Extra functions to generate haskell templates.
    -}

    -- | Integer literal template from 'Integral' types.
    integralE :: Integral a => a -> ExpQ
    integralE :: forall a. Integral a => a -> ExpQ
    integralE =  Lit -> ExpQ
    forall (m :: * -> *). Quote m => Lit -> m Exp
    litE (Lit -> ExpQ) -> (a -> Lit) -> a -> ExpQ
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Integer -> Lit
    integerL (Integer -> Lit) -> (a -> Integer) -> a -> Lit
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . a -> Integer
    forall a. Integral a => a -> Integer
    toInteger

    -- | Generate declaration template from name, type and expression.
    simpleValD :: Name -> TypeQ -> ExpQ -> Q [Dec]
    simpleValD :: Name -> TypeQ -> ExpQ -> Q [Dec]
    simpleValD Name
    var TypeQ
    typ ExpQ
    expr =  do
      sig <- Name -> TypeQ -> Q Dec
    forall (m :: * -> *). Quote m => Name -> m Type -> m Dec
    sigD Name
    var TypeQ
    typ
      val <- valD (varP var) (normalB expr) []
      return [sig, val]

    -- | May generate declaration template.
    maybeD :: (a -> Q [Dec]) -> Maybe a -> Q [Dec]
    maybeD :: forall a. (a -> Q [Dec]) -> Maybe a -> Q [Dec]
    maybeD =  Q [Dec] -> (a -> Q [Dec]) -> Maybe a -> Q [Dec]
    forall b a. b -> (a -> b) -> Maybe a -> b
    maybe ([Dec] -> Q [Dec]
    forall a. a -> Q a
    forall (m :: * -> *) a. Monad m => a -> m a
    return [])

    {- $prettyPrint
    Pretty printing for haskell templates.
    -}

    -- | Helper function for pretty printing 'Q' Monad.
    pprQ :: (Functor m, Quasi m, Ppr a) => Q a -> m Doc
    pprQ :: forall (m :: * -> *) a. (Functor m, Quasi m, Ppr a) => Q a -> m Doc
    pprQ =  (a -> Doc) -> m a -> m Doc
    forall a b. (a -> b) -> m a -> m b
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    fmap a -> Doc
    forall a. Ppr a => a -> Doc
    ppr (m a -> m Doc) -> (Q a -> m a) -> Q a -> m Doc
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . Q a -> m a
    forall (m :: * -> *) a. Quasi m => Q a -> m a
    runQ

    {- $compileMessage
    Functions to display or to raise compile messages from codes
    which generating haskell templates.

    Only messages directly generated by 'Q' monad report actions
    are handled by ghc loggers.

    > -- Handled by ghc logger
    > qReport False "Foo"

    > -- Not handled by ghc logger
    > runIO . runQ $ qReport False "Foo"
     -}

    -- | Print compile warnings from TH code.
    reportWarning :: String -> Q ()
    reportWarning :: String -> Q ()
    reportWarning =  Bool -> String -> Q ()
    forall (m :: * -> *). Quasi m => Bool -> String -> m ()
    qReport Bool
    False

    -- | Print compile errors from TH code.
    reportError :: String -> Q ()
    reportError :: String -> Q ()
    reportError =  Bool -> String -> Q ()
    forall (m :: * -> *). Quasi m => Bool -> String -> m ()
    qReport Bool
    True