summaryrefslogtreecommitdiff
path: root/testsuite/tests/parser
diff options
context:
space:
mode:
authorMatthew Pickering <matthewtpickering@gmail.com>2020-05-26 13:31:13 +0100
committerBen Gamari <ben@smart-cactus.org>2020-07-21 14:47:19 -0400
commita625719284db7c69fa3d122e829291a16960e85f (patch)
treeb15fb36d401ea100a93ec9baec4c6b8c36adffba /testsuite/tests/parser
parent05910be1ac5c1f485132d2c8bd1ceb4f86e06db5 (diff)
downloadhaskell-a625719284db7c69fa3d122e829291a16960e85f.tar.gz
Use a newtype `Code` for the return type of typed quotations (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 'testsuite/tests/parser')
-rw-r--r--testsuite/tests/parser/should_compile/Proposal229f_instances.hs6
1 files changed, 3 insertions, 3 deletions
diff --git a/testsuite/tests/parser/should_compile/Proposal229f_instances.hs b/testsuite/tests/parser/should_compile/Proposal229f_instances.hs
index 2bd5a8ee19..357a53fcb4 100644
--- a/testsuite/tests/parser/should_compile/Proposal229f_instances.hs
+++ b/testsuite/tests/parser/should_compile/Proposal229f_instances.hs
@@ -8,8 +8,8 @@ import Data.String
import Language.Haskell.TH
import Language.Haskell.TH.Syntax
-instance IsList (Q (TExp String)) where
- type Item (Q (TExp String)) = Char
+instance IsList (Code Q String) where
+ type Item (Code Q String) = Char
fromList = liftTyped
toList = undefined
@@ -18,7 +18,7 @@ instance IsList (Q Exp) where
fromList = lift
toList = undefined
-instance IsString (Q (TExp String)) where
+instance IsString (Code Q String) where
fromString = liftTyped
instance IsString (Q Exp) where