diff options
author | Matthew Pickering <matthewtpickering@gmail.com> | 2019-11-27 15:29:44 +0000 |
---|---|---|
committer | Marge Bot <ben+marge-bot@smart-cactus.org> | 2020-01-12 21:28:47 -0500 |
commit | 9129210f7e9937c1065330295f06524661575839 (patch) | |
tree | 8eee18f92d23eb2fe39adecda1d547fa8d9fa7cb /docs | |
parent | 49f83a0de12a7c02f4a6e99d26eaa362a373afa5 (diff) | |
download | haskell-9129210f7e9937c1065330295f06524661575839.tar.gz |
Overloaded Quotation Brackets (#246)
This patch implements overloaded quotation brackets which generalise the
desugaring of all quotation forms in terms of a new minimal interface.
The main change is that a quotation, for example, [e| 5 |], will now
have type `Quote m => m Exp` rather than `Q Exp`. The `Quote` typeclass
contains a single method for generating new names which is used when
desugaring binding structures.
The return type of functions from the `Lift` type class, `lift` and `liftTyped` have
been restricted to `forall m . Quote m => m Exp` rather than returning a
result in a Q monad.
More details about the feature can be read in the GHC proposal.
https://github.com/ghc-proposals/ghc-proposals/blob/master/proposals/0246-overloaded-bracket.rst
Diffstat (limited to 'docs')
-rw-r--r-- | docs/users_guide/8.12.1-notes.rst | 4 | ||||
-rw-r--r-- | docs/users_guide/glasgow_exts.rst | 69 |
2 files changed, 58 insertions, 15 deletions
diff --git a/docs/users_guide/8.12.1-notes.rst b/docs/users_guide/8.12.1-notes.rst index 69890b2c10..70bb901b07 100644 --- a/docs/users_guide/8.12.1-notes.rst +++ b/docs/users_guide/8.12.1-notes.rst @@ -32,6 +32,10 @@ Runtime system Template Haskell ~~~~~~~~~~~~~~~~ + - Implement the Overloaded Quotations proposal (#246). The type of all quotation + forms have now been generalised in terms of a minimal interface necessary for the + implementation rather than the overapproximation of the ``Q`` monad. + ``ghc-prim`` library ~~~~~~~~~~~~~~~~~~~~ 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, |