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


-- | The 'Lift' typeclass.
--   
--   The stable home of TemplateHaskell's <a>Lift</a> typeclass, which
--   implements cross-stage persistence for Template Haskell.
@package template-haskell-lift
@version 0.1.0.0

module Language.Haskell.TH.Lift

-- | A <a>Lift</a> instance can have any of its values turned into a
--   Template Haskell expression. This is needed when a value used within a
--   Template Haskell quotation is bound outside the Oxford brackets
--   (<tt>[| ... |]</tt> or <tt>[|| ... ||]</tt>) but not at the top level.
--   As an example:
--   
--   <pre>
--   add1 :: Int -&gt; Code Q Int
--   add1 x = [|| x + 1 ||]
--   </pre>
--   
--   Template Haskell has no way of knowing what value <tt>x</tt> will take
--   on at splice-time, so it requires the type of <tt>x</tt> to be an
--   instance of <a>Lift</a>.
--   
--   A <a>Lift</a> instance must satisfy <tt>$(lift x) ≡ x</tt> and
--   <tt>$$(liftTyped x) ≡ x</tt> for all <tt>x</tt>, where <tt>$(...)</tt>
--   and <tt>$$(...)</tt> are Template Haskell splices. It is additionally
--   expected that <tt><a>lift</a> x ≡ <a>unTypeCode</a> (<a>liftTyped</a>
--   x)</tt>.
--   
--   <a>Lift</a> instances can be derived automatically by use of the
--   <tt>-XDeriveLift</tt> GHC language extension:
--   
--   <pre>
--   {-# LANGUAGE DeriveLift #-}
--   module Foo where
--   
--   import Language.Haskell.TH.Syntax
--   
--   data Bar a = Bar1 a (Bar a) | Bar2 String
--     deriving Lift
--   </pre>
--   
--   Representation-polymorphic since <i>template-haskell-2.16.0.0</i>.
--   
--   This is exposed both from the <tt>template-haskell-lift</tt> and
--   <tt>template-haskell</tt> packages. Consider importing it from the
--   more stable <tt>template-haskell-lift</tt> if you don't need the full
--   breadth of the <tt>template-haskell</tt> interface.
class Lift (t :: TYPE r)

-- | Turn a value into a Template Haskell expression, suitable for use in a
--   splice.
lift :: (Lift t, Quote m) => t -> m Exp
($dmlift) :: forall m. (Lift t, r ~ LiftedRep, Quote m) => t -> m Exp

-- | Turn a value into a Template Haskell typed expression, suitable for
--   use in a typed splice.
liftTyped :: forall (m :: Type -> Type). (Lift t, Quote m) => t -> Code m t

-- | In short, <a>Q</a> provides the <a>Quasi</a> operations in one neat
--   monad for the user.
--   
--   The longer story, is that <a>Q</a> wraps an arbitrary
--   <a>Quasi</a>-able monad. The perceptive reader notices that
--   <a>Quasi</a> has only two instances, <a>Q</a> itself and <a>IO</a>,
--   neither of which have concrete implementations.<a>Q</a> plays the
--   trick of <a>dependency inversion</a>, providing an abstract interface
--   for the user which is later concretely fufilled by an concrete
--   <a>Quasi</a> instance, internal to GHC.
data Q a

-- | Represents an expression which has type <tt>a</tt>, built in monadic
--   context <tt>m</tt>. Built on top of <a>TExp</a>, typed expressions
--   allow for type-safe splicing via:
--   
--   <ul>
--   <li>typed quotes, written as <tt>[|| ... ||]</tt> where <tt>...</tt>
--   is an expression; if that expression has type <tt>a</tt>, then the
--   quotation has type <tt>Quote m =&gt; Code m a</tt></li>
--   <li>typed splices inside of typed quotes, written as <tt>$$(...)</tt>
--   where <tt>...</tt> is an arbitrary expression of type <tt>Quote m
--   =&gt; Code m a</tt></li>
--   </ul>
--   
--   Traditional expression quotes and splices let us construct ill-typed
--   expressions:
--   
--   <pre>
--   &gt;&gt;&gt; fmap ppr $ runQ (unTypeCode [| True == $( [| "foo" |] ) |])
--   GHC.Internal.Types.True GHC.Internal.Classes.== "foo"
--   
--   &gt;&gt;&gt; GHC.Internal.Types.True GHC.Internal.Classes.== "foo"
--   &lt;interactive&gt; error:
--       • Couldn't match expected type ‘Bool’ with actual type ‘[Char]’
--       • In the second argument of ‘(==)’, namely ‘"foo"’
--         In the expression: True == "foo"
--         In an equation for ‘it’: it = True == "foo"
--   </pre>
--   
--   With typed expressions, the type error occurs when <i>constructing</i>
--   the Template Haskell expression:
--   
--   <pre>
--   &gt;&gt;&gt; fmap ppr $ runQ (unTypeCode [|| True == $$( [|| "foo" ||] ) ||])
--   &lt;interactive&gt; error:
--       • Couldn't match type ‘[Char]’ with ‘Bool’
--         Expected type: Code Q Bool
--           Actual type: Code Q [Char]
--       • In the Template Haskell quotation [|| "foo" ||]
--         In the expression: [|| "foo" ||]
--         In the Template Haskell splice $$([|| "foo" ||])
--   </pre>
data Code (m :: Type -> Type) (a :: TYPE r)

-- | The <a>Quote</a> class implements the minimal interface which is
--   necessary for desugaring quotations.
--   
--   <ul>
--   <li>The <tt>Monad m</tt> superclass is needed to stitch together the
--   different AST fragments.</li>
--   <li><a>newName</a> is used when desugaring binding structures such as
--   lambdas to generate fresh names.</li>
--   </ul>
--   
--   Therefore the type of an untyped quotation in GHC is `Quote m =&gt; m
--   Exp`
--   
--   For many years the type of a quotation was fixed to be `Q Exp` but by
--   more precisely specifying the minimal interface it enables the
--   <a>Exp</a> to be extracted purely from the quotation without
--   interacting with <a>Q</a>.
class Monad m => Quote (m :: Type -> Type)

-- | A Haskell expression.
data Exp

-- | Convert an implementation of <a>lift</a> into one for
--   <a>liftTyped</a>.
defaultLiftTyped :: forall a (m :: Type -> Type). (Lift a, Quote m) => a -> Code m a

-- | A compatibility shim for lifting an <tt>Addr#</tt> value.
liftAddrCompat :: Quote m => ForeignPtr Word8 -> Word -> Word -> m Exp

-- | A compatibility shim for lifting an <a>Int</a> value without
--   triggering bugs if <tt>RebindableSyntax</tt> is used in a module.
liftIntCompat :: Quote m => Integer -> m Exp
