-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | This package defines a <a>Language.Haskell.TH.Syntax.Compat</a>
--   module, which backports the <tt>Quote</tt> and <tt>Code</tt> types to
--   work across a wide range of <tt>template-haskell</tt> versions. The
--   <tt>makeRelativeToProject</tt> utility is also backported. On recent
--   versions of <tt>template-haskell</tt> (2.17.0.0 or later), this module
--   simply reexports definitions from <a>Language.Haskell.TH.Syntax</a>.
--   Refer to the Haddocks for <a>Language.Haskell.TH.Syntax.Compat</a> for
--   examples of how to use this module.
@package th-compat
@version 0.1.6


-- | This module exists to make it possible to define code that works
--   across a wide range of <tt>template-haskell</tt> versions with as
--   little CPP as possible. To that end, this module currently backports
--   the following <tt>template-haskell</tt> constructs:
--   
--   <ul>
--   <li>The <a>Quote</a> class</li>
--   <li>The <a>Code</a> type</li>
--   <li>The <a>getPackageRoot</a> and <a>makeRelativeToProject</a> utility
--   functions</li>
--   </ul>
--   
--   Refer to the Haddocks below for examples of how to use each of these
--   in a backwards-compatible way.
module Language.Haskell.TH.Syntax.Compat
class Monad m => Quote (m :: Type -> Type)
newName :: Quote m => String -> m Name

-- | Use a <a>Q</a> computation in a <a>Quote</a> context. This function is
--   only safe when the <a>Q</a> computation performs actions from the
--   <a>Quote</a> instance for <a>Q</a> or any of <a>Quote</a>'s subclasses
--   (<a>Functor</a>, <a>Applicative</a>, and <a>Monad</a>). Attempting to
--   perform actions from the <a>MonadFail</a>, <a>MonadIO</a>, or
--   <a>Quasi</a> instances for <a>Q</a> will result in runtime errors.
--   
--   This is useful when you have some <a>Q</a>-valued functions that only
--   performs actions from <a>Quote</a> and wish to generalise it from
--   <a>Q</a> to <a>Quote</a> without having to rewrite the internals of
--   the function. This is especially handy for code defined in terms of
--   combinators from <a>Language.Haskell.TH.Lib</a>, which were all
--   hard-coded to <a>Q</a> prior to <tt>template-haskell-2.17.0.0</tt>.
--   For instance, consider this function:
--   
--   <pre>
--   apply :: <a>Exp</a> -&gt; <a>Exp</a> -&gt; <a>Q</a> <a>Exp</a>
--   apply f x = <a>appE</a> (return x) (return y)
--   </pre>
--   
--   There are two ways to generalize this function to use <a>Quote</a> in
--   a backwards-compatible way. One way to do so is to rewrite
--   <tt>apply</tt> to avoid the use of <a>appE</a>, like so:
--   
--   <pre>
--   applyQuote :: <a>Quote</a> m =&gt; <a>Exp</a> -&gt; <a>Exp</a> -&gt; m <a>Exp</a>
--   applyQuote f x = return (<a>AppE</a> x y)
--   </pre>
--   
--   For a small example like <tt>applyQuote</tt>, there isn't much work
--   involved. But this can become tiresome for larger examples. In such
--   cases, <a>unsafeQToQuote</a> can do the heavy lifting for you. For
--   example, <tt>applyQuote</tt> can also be defined as:
--   
--   <pre>
--   applyQuote :: <a>Quote</a> m =&gt; <a>Exp</a> -&gt; <a>Exp</a> -&gt; m <a>Exp</a>
--   applyQuote f x = <a>unsafeQToQuote</a> (apply f x)
--   </pre>
unsafeQToQuote :: Quote m => Q a -> m a

-- | Discard the type annotation and produce a plain Template Haskell
--   expression
--   
--   Levity-polymorphic since <i>template-haskell-2.16.0.0</i>.
--   
--   This is a variant of the <a>unTypeQ</a> function that is always
--   guaranteed to use a <a>Quote</a> constraint, even on old versions of
--   <tt>template-haskell</tt>.
--   
--   As this function interacts with typed Template Haskell, this function
--   is only defined on <tt>template-haskell-2.9.0.0</tt> (GHC 7.8) or
--   later.
unTypeQQuote :: forall a m. Quote m => m (TExp a) -> m Exp

-- | Annotate the Template Haskell expression with a type
--   
--   This is unsafe because GHC cannot check for you that the expression
--   really does have the type you claim it has.
--   
--   Levity-polymorphic since <i>template-haskell-2.16.0.0</i>.
--   
--   This is a variant of the <a>unsafeTExpCoerce</a> function that is
--   always guaranteed to use a <a>Quote</a> constraint, even on old
--   versions of <tt>template-haskell</tt>.
--   
--   As this function interacts with typed Template Haskell, this function
--   is only defined on <tt>template-haskell-2.9.0.0</tt> (GHC 7.8) or
--   later.
unsafeTExpCoerceQuote :: forall a m. Quote m => m Exp -> m (TExp a)

-- | Turn a value into a Template Haskell expression, suitable for use in a
--   splice.
--   
--   This is a variant of the <a>lift</a> method of <a>Lift</a> that is
--   always guaranteed to use a <a>Quote</a> constraint, even on old
--   versions of <tt>template-haskell</tt>.
--   
--   Levity-polymorphic since <i>template-haskell-2.17.0.0</i>.
liftQuote :: (Lift t, Quote m) => t -> m Exp

-- | Turn a value into a Template Haskell typed expression, suitable for
--   use in a typed splice.
--   
--   This is a variant of the <a>liftTyped</a> method of <a>Lift</a> that
--   is always guaranteed to use a <a>Quote</a> constraint and return a
--   <a>Code</a>, even on old versions of <tt>template-haskell</tt>.
--   
--   As this function interacts with typed Template Haskell, this function
--   is only defined on <tt>template-haskell-2.9.0.0</tt> (GHC 7.8) or
--   later. While the <a>liftTyped</a> method of <a>Lift</a> was first
--   introduced in <tt>template-haskell-2.16.0.0</tt>, we are able to
--   backport it back to <tt>template-haskell-2.9.0.0</tt> by making use of
--   the <a>lift</a> method on older versions of <tt>template-haskell</tt>.
--   This crucially relies on the <a>Lift</a> law that <tt><a>lift</a> x ≡
--   <a>unTypeQ</a> (<a>liftTyped</a> x)</tt> to work, so beware if you use
--   <a>liftTypedQuote</a> with an unlawful <a>Lift</a> instance.
--   
--   Levity-polymorphic since <i>template-haskell-2.17.0.0</i>.
liftTypedQuote :: forall t (m :: Type -> Type). (Lift t, Quote m) => t -> Code m t

-- | This is a variant of the <a>liftString</a> function that is always
--   guaranteed to use a <a>Quote</a> constraint, even on old versions of
--   <tt>template-haskell</tt>.
liftStringQuote :: Quote m => String -> m Exp
newtype Code (m :: Type -> Type) (a :: TYPE r)
Code :: m (TExp a) -> Code (m :: Type -> Type) (a :: TYPE r)
[examineCode] :: Code (m :: Type -> Type) (a :: TYPE r) -> m (TExp a)
type CodeQ = Code Q

-- | A class that allows one to smooth over the differences between
--   <tt><a>Code</a> <tt>m</tt> a</tt> (the type of typed Template Haskell
--   quotations on <tt>template-haskell-2.17.0.0</tt> or later) and
--   <tt><tt>m</tt> (<tt>TExp</tt> a)</tt> (the type of typed Template
--   Haskell quotations on older versions of <tt>template-haskell</tt>).
--   Here are two examples that demonstrate how to use each method of
--   <a>IsCode</a>:
--   
--   <pre>
--   {-# LANGUAGE TemplateHaskell #-}
--   
--   import <a>Language.Haskell.TH</a>
--   import <a>Language.Haskell.TH.Syntax.Compat</a>
--   
--   -- <a>toCode</a> will ensure that the end result is a <a>Code</a>, regardless of
--   -- whether the quote itself returns a <a>Code</a> or a <tt>TExp</tt>.
--   myCode :: <a>Code</a> <a>Q</a> Int
--   myCode = <a>toCode</a> [|| 42 ||]
--   
--   -- <a>fromCode</a> will ensure that the input <a>Code</a> is suitable for splicing
--   -- (i.e., it will return a <a>Code</a> or a <tt>TExp</tt> depending on the
--   -- <tt>template-haskell</tt> version in use).
--   fortyTwo :: Int
--   fortyTwo = $$(<a>fromCode</a> myCode)
--   </pre>
--   
--   Levity-polymorphic since <i>template-haskell-2.16.0.0</i>.
class IsCode (q :: Type -> Type) (a :: TYPE r) c | c -> a q

-- | Convert something to a <a>Code</a>.
toCode :: IsCode q a c => c -> Code q a

-- | Convert to something from a <a>Code</a>.
fromCode :: IsCode q a c => Code q a -> c
unsafeCodeCoerce :: forall a m. Quote m => m Exp -> Code m a
liftCode :: forall a m. m (TExp a) -> Code m a
unTypeCode :: forall a m. Quote m => Code m a -> m Exp
hoistCode :: Monad m => (forall x. () => m x -> n x) -> Code m a -> Code n a
bindCode :: Monad m => m a -> (a -> Code m b) -> Code m b
bindCode_ :: Monad m => m a -> Code m b -> Code m b
joinCode :: Monad m => m (Code m a) -> Code m a

-- | <tt><a>Splice</a> m a</tt> is a type alias for:
--   
--   <ul>
--   <li><tt><a>Code</a> m a</tt>, if using
--   <tt>template-haskell-2.17.0.0</tt> or later, or</li>
--   <li><tt>m (<a>TExp</a> a)</tt>, if using an older version of
--   <tt>template-haskell</tt>.</li>
--   </ul>
--   
--   This should be used with caution, as its definition differs depending
--   on which version of <tt>template-haskell</tt> you are using. It is
--   mostly useful for contexts in which one is writing a definition that
--   is intended to be used directly in a typed Template Haskell splice, as
--   the types of TH splices differ between <tt>template-haskell</tt>
--   versions as well.
--   
--   Levity-polymorphic since <i>template-haskell-2.16.0.0</i>.
type Splice = Code

-- | <tt><a>SpliceQ</a> a</tt> is a type alias for:
--   
--   <ul>
--   <li><tt><a>Code</a> <a>Q</a> a</tt>, if using
--   <tt>template-haskell-2.17.0.0</tt> or later, or</li>
--   <li><tt><a>Q</a> (<a>TExp</a> a)</tt>, if using an older version of
--   <tt>template-haskell</tt>.</li>
--   </ul>
--   
--   This should be used with caution, as its definition differs depending
--   on which version of <tt>template-haskell</tt> you are using. It is
--   mostly useful for contexts in which one is writing a definition that
--   is intended to be used directly in a typed Template Haskell splice, as
--   the types of TH splices differ between <tt>template-haskell</tt>
--   versions as well.
--   
--   Levity-polymorphic since <i>template-haskell-2.16.0.0</i>.
type SpliceQ = Splice Q

-- | A variant of <a>bindCode</a> that works over <a>Splice</a>s. Because
--   this function uses <a>Splice</a>, the type of this function will be
--   different depending on which version of <tt>template-haskell</tt> you
--   are using. (See the Haddocks for <a>Splice</a> for more information on
--   this point.)
--   
--   Levity-polymorphic since <i>template-haskell-2.16.0.0</i>.
bindSplice :: Monad m => m a -> (a -> Splice m b) -> Splice m b

-- | A variant of <a>bindCode_</a> that works over <a>Splice</a>s. Because
--   this function uses <a>Splice</a>, the type of this function will be
--   different depending on which version of <tt>template-haskell</tt> you
--   are using. (See the Haddocks for <a>Splice</a> for more information on
--   this point.)
--   
--   Levity-polymorphic since <i>template-haskell-2.16.0.0</i>.
bindSplice_ :: Monad m => m a -> Splice m b -> Splice m b

-- | A variant of <a>examineCode</a> that takes a <a>Splice</a> as an
--   argument. Because this function takes a <a>Splice</a> as an argyment,
--   the type of this function will be different depending on which version
--   of <tt>template-haskell</tt> you are using. (See the Haddocks for
--   <a>Splice</a> for more information on this point.)
--   
--   Levity-polymorphic since <i>template-haskell-2.16.0.0</i>.
examineSplice :: Splice m a -> m (TExp a)

-- | A variant of <a>hoistCode</a> that works over <a>Splice</a>s. Because
--   this function uses <a>Splice</a>, the type of this function will be
--   different depending on which version of <tt>template-haskell</tt> you
--   are using. (See the Haddocks for <a>Splice</a> for more information on
--   this point.)
--   
--   Levity-polymorphic since <i>template-haskell-2.16.0.0</i>.
hoistSplice :: Monad m => (forall x. () => m x -> n x) -> Splice m a -> Splice n a

-- | A variant of <a>joinCode</a> that works over <a>Splice</a>s. Because
--   this function uses <a>Splice</a>, the type of this function will be
--   different depending on which version of <tt>template-haskell</tt> you
--   are using. (See the Haddocks for <a>Splice</a> for more information on
--   this point.)
--   
--   Levity-polymorphic since <i>template-haskell-2.16.0.0</i>.
joinSplice :: Monad m => m (Splice m a) -> Splice m a

-- | A variant of <a>liftCode</a> that returns a <a>Splice</a>. Because
--   this function returns a <a>Splice</a>, the return type of this
--   function will be different depending on which version of
--   <tt>template-haskell</tt> you are using. (See the Haddocks for
--   <a>Splice</a> for more information on this point.)
--   
--   Levity-polymorphic since <i>template-haskell-2.16.0.0</i>.
liftSplice :: forall a m. m (TExp a) -> Splice m a

-- | A variant of <a>liftTypedQuote</a> that is:
--   
--   <ol>
--   <li>Always implemented in terms of <a>lift</a> behind the scenes,
--   and</li>
--   <li>Returns a <a>Splice</a>. This means that the return type of this
--   function will be different depending on which version of
--   <tt>template-haskell</tt> you are using. (See the Haddocks for
--   <a>Splice</a> for more information on this point.)</li>
--   </ol>
--   
--   This is especially useful for minimizing CPP in one particular
--   scenario: implementing <a>liftTyped</a> in hand-written <a>Lift</a>
--   instances where the corresponding <a>lift</a> implementation cannot be
--   derived. For instance, consider this example from the <tt>text</tt>
--   library:
--   
--   <pre>
--   instance <a>Lift</a> Text where
--     <a>lift</a> = appE (varE 'pack) . stringE . unpack
--   #if MIN_VERSION_template_haskell(2,17,0)
--     <a>liftTyped</a> = <a>unsafeCodeCoerce</a> . <a>lift</a>
--   #elif MIN_VERSION_template_haskell(2,16,0)
--     <a>liftTyped</a> = <a>unsafeTExpCoerce</a> . <a>lift</a>
--   #endif
--   </pre>
--   
--   The precise details of how this <a>lift</a> implementation works are
--   not important, only that it is something that <tt>DeriveLift</tt>
--   could not generate. The main point of this example is to illustrate
--   how tiresome it is to write the CPP necessary to define
--   <a>liftTyped</a> in a way that works across multiple versions of
--   <tt>template-haskell</tt>. With <a>liftTypedFromUntypedSplice</a>,
--   however, this becomes slightly easier to manage:
--   
--   <pre>
--   instance <a>Lift</a> Text where
--     <a>lift</a> = appE (varE 'pack) . stringE . unpack
--   #if MIN_VERSION_template_haskell(2,16,0)
--     <a>liftTyped</a> = <a>liftTypedFromUntypedSplice</a>
--   #endif
--   </pre>
--   
--   Note that due to the way this function is defined, this will only work
--   for <a>Lift</a> instances <tt>t</tt> such that <tt>(t :: Type)</tt>.
--   If you wish to manually define <a>liftTyped</a> for a type with a
--   different kind, you will have to use <a>unsafeSpliceCoerce</a> to
--   overcome levity polymorphism restrictions.
liftTypedFromUntypedSplice :: forall t (m :: Type -> Type). (Lift t, Quote m) => t -> Splice m t

-- | Unsafely convert an untyped splice representation into a typed
--   <a>Splice</a> representation. Because this function returns a
--   <a>Splice</a>, the return type of this function will be different
--   depending on which version of <tt>template-haskell</tt> you are using.
--   (See the Haddocks for <a>Splice</a> for more information on this
--   point.)
--   
--   This is especially useful for minimizing CPP when:
--   
--   <ol>
--   <li>You need to implement <a>liftTyped</a> in a hand-written
--   <a>Lift</a> instance where the corresponding <a>lift</a>
--   implementation cannot be derived, and</li>
--   <li>The data type receiving a <a>Lift</a> instance has a kind besides
--   <tt>Type</tt>.</li>
--   </ol>
--   
--   Condition (2) is important because while it is possible to simply
--   define <tt>'Syntax.liftTyped = <a>liftTypedFromUntypedSplice</a></tt>
--   for <a>Lift</a> instances <tt>t</tt> such that <tt>(t :: Type)</tt>,
--   this will not work for types with different types, such as unboxed
--   types or unlifted newtypes. This is because GHC restrictions prevent
--   defining <a>liftTypedFromUntypedSplice</a> in a levity polymorphic
--   fashion, so one must use <a>unsafeSpliceCoerce</a> to work around
--   these restrictions. Here is an example of how to use
--   <a>unsafeSpliceCoerce</a>:
--   
--   <pre>
--   instance <a>Lift</a> Int# where
--     <a>lift</a> x = litE (intPrimL (fromIntegral (I# x)))
--   #if MIN_VERSION_template_haskell(2,16,0)
--     <a>liftTyped</a> x = <a>unsafeSpliceCoerce</a> (<a>lift</a> x)
--   #endif
--   </pre>
--   
--   Levity-polymorphic since <i>template-haskell-2.16.0.0</i>.
unsafeSpliceCoerce :: forall a m. Quote m => m Exp -> Splice m a

-- | A variant of <a>unTypeCode</a> that takes a <a>Splice</a> as an
--   argument. Because this function takes a <a>Splice</a> as an argyment,
--   the type of this function will be different depending on which version
--   of <tt>template-haskell</tt> you are using. (See the Haddocks for
--   <a>Splice</a> for more information on this point.)
--   
--   Levity-polymorphic since <i>template-haskell-2.16.0.0</i>.
unTypeSplice :: forall a m. Quote m => Splice m a -> m Exp

-- | Lift a <tt><a>TExp</a> a</tt> into a <a>Splice</a>. This is useful
--   when splicing in the result of a computation into a typed QuasiQuoter.
--   
--   One example is <a>traverse</a>ing over a list of elements and
--   returning an expression from each element.
--   
--   <pre>
--   mkInt :: <a>String</a> -&gt; <a>Q</a> (<a>TExp</a> <a>Int</a>)
--   mkInt str = [|| length $$str ||]
--   
--   mkInts :: [<a>String</a>] -&gt; <a>Q</a> [<a>TExp</a> <a>Int</a>]
--   mkInts = traverse mkInt
--   </pre>
--   
--   This gives us a list of <a>TExp</a>, not a <a>TExp</a> of a list. We
--   can push the list inside the type with this function:
--   
--   <pre>
--   listTE :: [<a>TExp</a> a] -&gt; <a>TExp</a> [a]
--   listTE = <a>TExp</a> . <a>ListE</a> . <a>map</a> <a>unType</a>
--   </pre>
--   
--   In a <tt>do</tt> block using <a>liftSplice</a>, we can bind the
--   resulting
--   
--   <tt><a>TExp</a> [<a>Int</a>]</tt> out of the expression.
--   
--   <pre>
--   foo :: <a>Q</a> (<a>TExp</a> Int)
--   foo = do
--        ints &lt;- mkInts ["hello", "world", "goodybe", "bob"]
--        [|| sum $$(pure (listTE ints)) ||]
--   </pre>
--   
--   Prior to GHC 9, with the <a>Q</a> type, we can write <tt><a>pure</a>
--   :: <a>TExp</a> a -&gt; <a>Q</a> (<a>TExp</a> a)</tt>, which is a valid
--   thing to use in a typed quasiquoter. However, after GHC 9, this code
--   will fail to type check. There is no <a>Applicative</a> instance for
--   <tt><a>Code</a> m a</tt>, so we need another way to splice it in.
--   
--   A GHC 9 only solution can use <tt><a>Code</a> :: m (<a>TExp</a> a)
--   -&gt; Code m a</tt> and <a>pure</a> together, like: <tt><a>Code</a> .
--   <a>pure</a></tt>.
--   
--   With <a>expToSplice</a>, we can splice it in a backwards compatible
--   way. A fully backwards- and forwards-compatible example looks like
--   this:
--   
--   <pre>
--   mkInt :: <a>String</a> -&gt; <a>Q</a> <a>Int</a>
--   mkInt str = <a>examineSplice</a> [|| length $$str ||]
--   
--   mkInts :: [<a>String</a>] -&gt; <a>Q</a> [<a>TExp</a> <a>Int</a>]
--   mkInts = traverse mkInt
--   
--   foo :: <a>SpliceQ</a> <a>Int</a>
--   foo = <a>liftSplice</a> $ do
--        ints &lt;- mkInts ["hello", "world", "goodybe", "bob"]
--        <a>examineSplice</a> [|| sum $$(expToSplice (listTE ints)) ||]
--   </pre>
expToSplice :: forall (m :: Type -> Type) a. Applicative m => TExp a -> Splice m a
getPackageRoot :: Q FilePath
makeRelativeToProject :: FilePath -> Q FilePath
instance GHC.Internal.Base.Applicative m => GHC.Internal.Base.Applicative (Language.Haskell.TH.Syntax.Compat.QuoteToQuasi m)
instance GHC.Internal.Base.Functor m => GHC.Internal.Base.Functor (Language.Haskell.TH.Syntax.Compat.QuoteToQuasi m)
instance (texp GHC.Types.~ GHC.Internal.TH.Syntax.TExp a) => Language.Haskell.TH.Syntax.Compat.IsCode GHC.Internal.TH.Syntax.Q a (GHC.Internal.TH.Syntax.Q texp)
instance GHC.Internal.TH.Syntax.Quote q => Language.Haskell.TH.Syntax.Compat.IsCode q a (GHC.Internal.TH.Syntax.Code q a)
instance GHC.Internal.Base.Monad m => GHC.Internal.Control.Monad.Fail.MonadFail (Language.Haskell.TH.Syntax.Compat.QuoteToQuasi m)
instance GHC.Internal.Base.Monad m => GHC.Internal.Control.Monad.IO.Class.MonadIO (Language.Haskell.TH.Syntax.Compat.QuoteToQuasi m)
instance GHC.Internal.Base.Monad m => GHC.Internal.Base.Monad (Language.Haskell.TH.Syntax.Compat.QuoteToQuasi m)
instance GHC.Internal.TH.Syntax.Quote m => GHC.Internal.TH.Syntax.Quasi (Language.Haskell.TH.Syntax.Compat.QuoteToQuasi m)
