diff options
author | Matthew Pickering <matthewtpickering@gmail.com> | 2020-05-26 13:31:13 +0100 |
---|---|---|
committer | Sylvain Henry <sylvain@haskus.fr> | 2020-07-21 08:48:20 +0200 |
commit | e2d5d80d24a931e5351e64017694ab8aa84c6c1d (patch) | |
tree | baaec48b1c9c47a1308eb1cb6757c86ef54ee4ef /libraries/template-haskell/Language/Haskell/TH.hs | |
parent | c26e81d116a653b5259aeb290fb1e697efe3382a (diff) | |
download | haskell-wip/proposal-195.tar.gz |
Use a newtype `Code` for the return type of typed quotations (Proposal #195)wip/proposal-195
There are three problems with the current API:
1. It is hard to properly write instances for ``Quote m => m (TExp a)`` as the type is the composition
of two type constructors. Doing so in your program involves making your own newtype and
doing a lot of wrapping/unwrapping.
For example, if I want to create a language which I can either run immediately or
generate code from I could write the following with the new API. ::
class Lang r where
_int :: Int -> r Int
_if :: r Bool -> r a -> r a -> r a
instance Lang Identity where
_int = Identity
_if (Identity b) (Identity t) (Identity f) = Identity (if b then t else f)
instance Quote m => Lang (Code m) where
_int = liftTyped
_if cb ct cf = [|| if $$cb then $$ct else $$cf ||]
2. When doing code generation it is common to want to store code fragments in
a map. When doing typed code generation, these code fragments contain a
type index so it is desirable to store them in one of the parameterised
map data types such as ``DMap`` from ``dependent-map`` or ``MapF`` from
``parameterized-utils``.
::
compiler :: Env -> AST a -> Code Q a
data AST a where ...
data Ident a = ...
type Env = MapF Ident (Code Q)
newtype Code m a = Code (m (TExp a))
In this example, the ``MapF`` maps an ``Ident String`` directly to a ``Code Q String``.
Using one of these map types currently requires creating your own newtype and constantly
wrapping every quotation and unwrapping it when using a splice. Achievable, but
it creates even more syntactic noise than normal metaprogramming.
3. ``m (TExp a)`` is ugly to read and write, understanding ``Code m a`` is
easier. This is a weak reason but one everyone
can surely agree with.
Updates text submodule.
Diffstat (limited to 'libraries/template-haskell/Language/Haskell/TH.hs')
-rw-r--r-- | libraries/template-haskell/Language/Haskell/TH.hs | 2 |
1 files changed, 2 insertions, 0 deletions
diff --git a/libraries/template-haskell/Language/Haskell/TH.hs b/libraries/template-haskell/Language/Haskell/TH.hs index 36529e54dc..2da2bd61c6 100644 --- a/libraries/template-haskell/Language/Haskell/TH.hs +++ b/libraries/template-haskell/Language/Haskell/TH.hs @@ -50,6 +50,8 @@ module Language.Haskell.TH( -- * Typed expressions TExp, unType, + Code(..), unTypeCode, unsafeCodeCoerce, hoistCode, bindCode, + bindCode_, joinCode, liftCode, -- * Names Name, NameSpace, -- Abstract |