summaryrefslogtreecommitdiff
path: root/docs/users_guide/glasgow_exts.rst
diff options
context:
space:
mode:
Diffstat (limited to 'docs/users_guide/glasgow_exts.rst')
-rw-r--r--docs/users_guide/glasgow_exts.rst69
1 files changed, 54 insertions, 15 deletions
diff --git a/docs/users_guide/glasgow_exts.rst b/docs/users_guide/glasgow_exts.rst
index dcc43f9623..ea7bbac9cc 100644
--- a/docs/users_guide/glasgow_exts.rst
+++ b/docs/users_guide/glasgow_exts.rst
@@ -13117,7 +13117,7 @@ The :extension:`TemplateHaskellQuotes` extension is considered safe under
overrides the meaning of "." as an infix operator. If you want the
infix operator, put spaces around it.
- A splice can occur in place of
+ A top-level splice can occur in place of
- an expression; the spliced expression must have type ``Q Exp``
@@ -13133,32 +13133,70 @@ The :extension:`TemplateHaskellQuotes` extension is considered safe under
that declaration splices are not allowed anywhere except at top level
(outside any other declarations).
+ The ``Q`` monad is a monad defined in ``Language.Haskell.TH.Syntax`` which
+ supports several useful operations during code generation such as reporting
+ errors or looking up identifiers in the environment.
+
- A expression quotation is written in Oxford brackets, thus:
- ``[| ... |]``, or ``[e| ... |]``, where the "..." is an
- expression; the quotation has type ``Q Exp``.
+ expression; the quotation has type ``Quote m => m Exp``.
- ``[d| ... |]``, where the "..." is a list of top-level
- declarations; the quotation has type ``Q [Dec]``.
+ declarations; the quotation has type ``Quote m => m [Dec]``.
- ``[t| ... |]``, where the "..." is a type; the quotation has type
- ``Q Type``.
+ ``Quote m => m Type``.
- ``[p| ... |]``, where the "..." is a pattern; the quotation has
- type ``Q Pat``.
+ type ``Quote m => m Pat``.
+
+ The ``Quote`` type class is the minimal interface necessary to implement
+ the desugaring of quotations. The ``Q`` monad is an instance of ``Quote`` but
+ contains many more operations which are not needed for defining quotations.
See :ref:`pts-where` for using partial type signatures in quotations.
+- Splices can be nested inside quotation brackets. For example the fragment
+ representing ``1 + 2`` can be constructed using nested splices::
+
+ oneC, twoC, plusC :: Quote m => m Exp
+ oneC = [| 1 |]
+
+ twoC = [| 2 |]
+
+ plusC = [| $oneC + $twoC |]
+
+- The precise type of a quotation depends on the types of the nested splices inside it::
+
+ -- Add a redundant constraint to demonstrate that constraints on the
+ -- monad used to build the representation are propagated when using nested
+ -- splices.
+ f :: (Quote m, C m) => m Exp
+ f = [| 5 | ]
+
+ -- f is used in a nested splice so the constraint on f, namely C, is propagated
+ -- to a constraint on the whole representation.
+ g :: (Quote m, C m) => m Exp
+ g = [| $f + $f |]
+
+ Remember, a top-level splice still requires its argument to be of type ``Q Exp``.
+ So then splicing in ``g`` will cause ``m`` to be instantiated to ``Q``::
+
+ h :: Int
+ h = $(g) -- m ~ Q
+
+
- A *typed* expression splice is written ``$$x``, where ``x`` is
is an arbitrary expression.
- A typed expression splice can occur in place of an expression; the
+ A top-level typed expression splice can occur in place of an expression; the
spliced expression must have type ``Q (TExp a)``
- A *typed* expression quotation is written as ``[|| ... ||]``, or
``[e|| ... ||]``, where the "..." is an expression; if the "..."
expression has type ``a``, then the quotation has type
- ``Q (TExp a)``.
+ ``Quote m => m (TExp a)``.
Values of type ``TExp a`` may be converted to values of type ``Exp``
using the function ``unType :: TExp a -> Exp``.
@@ -13200,7 +13238,7 @@ The :extension:`TemplateHaskellQuotes` extension is considered safe under
import Language.Haskell.TH
- add1 :: Int -> Q Exp
+ add1 :: Quote m => Int -> m Exp
add1 x = [| x + 1 |]
Now consider a splice using ``add1`` in a separate
@@ -13215,13 +13253,14 @@ The :extension:`TemplateHaskellQuotes` extension is considered safe under
Template Haskell cannot know what the argument to ``add1`` will be at the
function's definition site, so a lifting mechanism is used to promote
- ``x`` into a value of type ``Q Exp``. This functionality is exposed to the
+ ``x`` into a value of type ``Quote m => m Exp``. This functionality is exposed to the
user as the ``Lift`` typeclass in the ``Language.Haskell.TH.Syntax``
module. If a type has a ``Lift`` instance, then any of its values can be
lifted to a Template Haskell expression: ::
class Lift t where
- lift :: t -> Q Exp
+ lift :: Quote m => t -> m Exp
+ liftTyped :: Quote m => t -> m (TExp t)
In general, if GHC sees an expression within Oxford brackets (e.g., ``[|
foo bar |]``, then GHC looks up each name within the brackets. If a name
@@ -13265,14 +13304,14 @@ The :extension:`TemplateHaskellQuotes` extension is considered safe under
quotation bracket are *not* run at compile time; they are run when the
bracket is spliced in, sometime later. For example, ::
- mkPat :: Q Pat
+ mkPat :: Quote m => m Pat
mkPat = [p| (x, y) |]
-- in another module:
foo :: (Char, String) -> String
foo $(mkPat) = x : z
- bar :: Q Exp
+ bar :: Quote m => m Exp
bar = [| \ $(mkPat) -> x : w |]
will fail with ``z`` being out of scope in the definition of ``foo`` but it
@@ -13402,7 +13441,7 @@ The :extension:`TemplateHaskellQuotes` extension is considered safe under
(Compared to the original paper, there are many differences of detail.
The syntax for a declaration splice uses "``$``" not "``splice``". The type of
-the enclosed expression must be ``Q [Dec]``, not ``[Q Dec]``. Typed expression
+the enclosed expression must be ``Quote m => m [Dec]``, not ``[Q Dec]``. Typed expression
splices and quotations are supported.)
.. ghc-flag:: -fenable-th-splice-warnings
@@ -13538,14 +13577,14 @@ and :file:`Printf.hs`:
-- Generate Haskell source code from a parsed representation
-- of the format string. This code will be spliced into
-- the module which calls "pr", at compile time.
- gen :: [Format] -> Q Exp
+ gen :: Quote m => [Format] -> m Exp
gen [D] = [| \n -> show n |]
gen [S] = [| \s -> s |]
gen [L s] = stringE s
-- Here we generate the Haskell code for the splice
-- from an input format string.
- pr :: String -> Q Exp
+ pr :: Quote m => String -> m Exp
pr s = gen (parse s)
Now run the compiler,