git.iko.soy/haskell-generate
on master help sign in
Refactor and add tutorial to README.md
c129f06Benno Fünfstück
README.md+100−1
@@ -1,6 +1,105 @@
1haskell-generate
1haskell-generate
2−====================
2+================
3
3
4[![Build Status](https://secure.travis-ci.org/bennofs/haskell-generate.png?branch=master)](http://travis-ci.org/bennofs/haskell-generate)
4[![Build Status](https://secure.travis-ci.org/bennofs/haskell-generate.png?branch=master)](http://travis-ci.org/bennofs/haskell-generate)
5
5
6+## Introduction
7+
8+If you want to generate haskell source code, you could build up haskell-src-exts AST and then pretty print it. But that's easy to screw up, because haskell-src-exts doesn't include tag it's AST with a type. This library aims to fill the gap, adding type information to haskell-src-exts expressions and also managing imports for you.
9+
10+## Getting started
11+
12+First, you need to import this library:
13+
14+```haskell
15+import Language.Haskell.Generate
16+```
17+
18+This module reexports `Language.Haskell.Exts.Syntax`, because haskell-generate builds on top of that.
19+
20+There are two main types in haskell-generate. The first is the monad `Generate` and the type alias `ExpG`. The `Generate` monad is used to track required imports. It also allows to generate unique names. `ExpG t` is just an action in the `Generate` monad that returns an expression of type `t`.
21+
22+How do you build expressions? There is a number of predefined expressions for the functions in the
23+Prelude. This allows you to just use these and combine them to new expressions. For example, let's define a expression that reads a file called "names":
24+
25+```haskell
26+readNamesFile' :: ExpG (IO String)
27+readNamesFile' = readFile' <>$ expr "names"
28+```
29+
30+Here we use `(<>$)` to apply the `readFile'` expression to the string `names`. `readFile'` is one of the expressions already provided by haskell-generate. All expressions that are provided by haskell-generate end with an apostrophe. You can find more of them in the module `Language.Haskell.Generate.PreludeDef`. The `expr` function is used to lift the string `names` into an expression of type `ExpG String`.
31+
32+Now that we have an expression, we need to bind it to a name in a module. For this job, we use another monad, the `ModuleM` monad. It allows you to bind expressions to names and then generate
33+a module with those names.
34+
35+Here's how we generate our module:
36+
37+```haskell
38+myModule :: ModuleG
39+myModule = do
40+ d <- addDecl (Ident "main") $ applyE2 bind' readNamesFile' putStrLn'
41+ return $ Just [exportFun d]
42+```
43+
44+`ModuleG` is again a type synonym for an action in the `ModuleM` monad. It must either return Nothing (which omits the export list) or an export list. In this case, we export the "main" function, which we previously defined using `addDecl`.
45+
46+The only thing left to do is to generate the actual source code for the module, for which we
47+use the `generateModule` function, which takes the module name as an argument:
48+
49+```haskell
50+main :: IO ()
51+main = putStrLn $ generateModule myModule "Main"
52+```
53+
54+If you run the program, you'll get the following output:
55+
56+```haskell
57+module Main (main) where
58+import qualified GHC.Base
59+import qualified System.IO
60+main
61+ = (GHC.Base.>>=) (System.IO.readFile ['n', 'a', 'm', 'e', 's'])
62+ System.IO.putStrLn
63+```
64+
65+If you run this code, you'll get the contents of the "names" file. The code is a bit ugly and uses
66+qualified imports to avoid name clashes, but it works.
67+
68+## Importing functions
69+
70+Until now, we've only used the predefined expressions from `Language.Haskell.Generate.PreludeDef`, but often you'll want to use definitions from other modules that you might want to use.
71+
72+You can do that using the `useValue` from haskell-generate. Let's look at the type of `useValue`:
73+
74+```haskell
75+useValue :: String -> Name -> ExpG t
76+```
77+
78+`useValue` takes a module name in which the function is defined and the name of the function. It returns an expression of any type you which. This function is unsafe, because it cannot check that the returned type is actually the type of the function. That's why you usually given `useValue` an explicit type signature.
79+
80+For example, suppose we want to use the function `permutations` from Data.List. We write the following definition for it:
81+
82+```haskell
83+permutations' :: ExpG ([a] -> [[a]]) -- Here we given an explicit type for permutations'. This is not checked, so make sure it's actually right!
84+permutations' = useValue "Data.List" (Ident "permutations") -- "permutations" is an identifier, not a symbol, so we use the "Ident" constructor.
85+```
86+
87+## Using TH to automagically import functions
88+
89+If the function you want to import is already available at compile time, you can use the template haskell code from `Language.Haskell.Generate.TH` to generate the expression definitions. This is the approach we use for the Prelude, as an example.
90+
91+Using the example from the previous section, we could also import the `permutations` function like this:
92+
93+```haskell
94+-- at the top of the file:
95+{-# LANGUAGE TemplateHaskell #-} -- Enable template haskell
96+import Data.List (permutations) -- The function needs to be available at compile time
97+
98+declareFunction 'permutations -- This generates the same code as above, but is more type-safe because you don't have to specify the type yourself.
99+```
100+
101+
102+## Contributing
103+
104+If you have an idea, a question or a bug report, open an issue on github. You can also find me on freenode in the #haskell channel, my nick is bennofs.
6
105
haskell-generate.cabal+2−1
@@ -37,7 +37,8 @@ library
37 , template-haskell
37 , template-haskell
38 exposed-modules:
38 exposed-modules:
39 Language.Haskell.Generate
39 Language.Haskell.Generate
40− Language.Haskell.Generate.Base
40+ Language.Haskell.Generate.Monad
41+ Language.Haskell.Generate.Expression
41 Language.Haskell.Generate.TH
42 Language.Haskell.Generate.TH
42 Language.Haskell.Generate.PreludeDef
43 Language.Haskell.Generate.PreludeDef
43
44
src/Language/Haskell/Generate.hs+2−1
@@ -2,5 +2,6 @@ module Language.Haskell.Generate
2 ( module X
2 ( module X
3 ) where
3 ) where
4
4
5−import Language.Haskell.Generate.Base as X
5+import Language.Haskell.Exts.Syntax as X
6+import Language.Haskell.Generate.Monad as X
6import Language.Haskell.Generate.PreludeDef as X
7import Language.Haskell.Generate.PreludeDef as X
src/Language/Haskell/Generate/Expression.hsnew file+12
@@ -0,0 +1,12 @@
1+module Language.Haskell.Generate.Expression
2+ ( Expression(..)
3+ , app
4+ ) where
5+
6+import Language.Haskell.Exts.Syntax
7+
8+newtype Expression t = Expression { runExpression :: Exp }
9+
10+app :: Expression (a -> b) -> Expression a -> Expression b
11+app (Expression a) (Expression b) = Expression $ App a b
12+
src/Language/Haskell/Generate/Base.hs → src/Language/Haskell/Generate/Monad.hsrenamed+58−50
@@ -3,9 +3,10 @@
3{-# LANGUAGE ScopedTypeVariables #-}
3{-# LANGUAGE ScopedTypeVariables #-}
4{-# LANGUAGE UndecidableInstances #-}
4{-# LANGUAGE UndecidableInstances #-}
5{-# LANGUAGE FlexibleInstances #-}
5{-# LANGUAGE FlexibleInstances #-}
6−module Language.Haskell.Generate.Base
6+module Language.Haskell.Generate.Monad
7− ( ExpM(..), ExpG, ExpType
7+ ( Generate(..), ExpG
8− , runExpM, newName
8+ , runGenerate, newName
9+ , returnE
9 , useValue, useCon, useVar
10 , useValue, useCon, useVar
10 , caseE
11 , caseE
11 , applyE, applyE2, applyE3, applyE4, applyE5, applyE6
12 , applyE, applyE2, applyE3, applyE4, applyE5, applyE6
@@ -19,6 +20,7 @@ module Language.Haskell.Generate.Base
19 , addDecl
20 , addDecl
20 , runModuleM
21 , runModuleM
21 , generateModule
22 , generateModule
23+ , generateExp
22 )
24 )
23 where
25 where
24
26
@@ -31,32 +33,30 @@ import qualified Data.Set as S
31import Language.Haskell.Exts.Pretty
33import Language.Haskell.Exts.Pretty
32import Language.Haskell.Exts.SrcLoc
34import Language.Haskell.Exts.SrcLoc
33import Language.Haskell.Exts.Syntax
35import Language.Haskell.Exts.Syntax
36+import Language.Haskell.Generate.Expression
34
37
35--------------------------------------------------------------------------------
38--------------------------------------------------------------------------------
36-- Generate expressions
39-- Generate expressions
37
40
38−-- | A ExpM is a monad used to track the imports that are needed for a given expression. Usually, you don't have to use
39−-- this type directly, but use combinators to combine several ExpM into bigger expressions. The t type parameter tracks
40−-- the type of the expression, so you don't accidently build expression that don't type check.
41−newtype ExpM t a = ExpM { unExpM :: StateT Integer (Writer (S.Set ModuleName)) a } deriving (Functor, Applicative, Monad)
41+newtype Generate a = Generate { unGenerate :: StateT Integer (Writer (S.Set ModuleName)) a } deriving (Functor, Applicative, Monad)
42
42
43−-- | The ExpG type is a ExpM computation that returns an expression. Usually, this is the end result of a function generating
43+runGenerate :: Generate a -> (a, S.Set ModuleName)
44−-- a haskell expression
44+runGenerate (Generate a) = runWriter $ evalStateT a 0
45−type ExpG t = ExpM t Exp
46
45
47−-- | Evaluate a ExpM action, returning the needed modules and the value.
46+type ExpG t = Generate (Expression t)
48−runExpM :: ExpM t a -> (a, S.Set ModuleName)
49−runExpM (ExpM expt) = runWriter $ evalStateT expt 0
50
47
51−unsafeCoerceE :: ExpM t a -> ExpM t' a
48+returnE :: Exp -> ExpG t
52−unsafeCoerceE (ExpM x) = ExpM x
49+returnE = return . Expression
50+
51+generateExp :: ExpG t -> String
52+generateExp = prettyPrint . runExpression . fst . runGenerate
53
53
54-- | Generate a case expression.
54-- | Generate a case expression.
55caseE :: ExpG x -> [(Pat, ExpG t)] -> ExpG t
55caseE :: ExpG x -> [(Pat, ExpG t)] -> ExpG t
56caseE v alt = do
56caseE v alt = do
57− v' <- unsafeCoerceE v
57+ v' <- v
58− alt' <- mapM (\(p,a) -> fmap (\a' -> Alt noLoc p (UnGuardedAlt a') (BDecls [])) a) alt
58+ alt' <- mapM (\(p,a) -> fmap (\a' -> Alt noLoc p (UnGuardedAlt $ runExpression a') (BDecls [])) a) alt
59− return $ Case v' alt'
59+ return $ Expression $ Case (runExpression v') alt'
60
60
61-- | Import a function from a module. This function is polymorphic in the type of the resulting expression,
61-- | Import a function from a module. This function is polymorphic in the type of the resulting expression,
62-- you should probably only use this function to define type-restricted specializations.
62-- you should probably only use this function to define type-restricted specializations.
@@ -67,31 +67,27 @@ caseE v alt = do
67-- > addInt = useValue "Prelude" $ Symbol "+"
67-- > addInt = useValue "Prelude" $ Symbol "+"
68--
68--
69useValue :: String -> Name -> ExpG a
69useValue :: String -> Name -> ExpG a
70−useValue md name = ExpM $ do
70+useValue md name = Generate $ do
71 lift $ tell $ S.singleton $ ModuleName md
71 lift $ tell $ S.singleton $ ModuleName md
72− return $ Var $ Qual (ModuleName md) name
72+ return $ Expression $ Var $ Qual (ModuleName md) name
73
73
74-- | Import a value constructor from a module. Returns the qualified name of the constructor.
74-- | Import a value constructor from a module. Returns the qualified name of the constructor.
75−useCon :: String -> Name -> ExpM t QName
75+useCon :: String -> Name -> Generate QName
76−useCon md name = ExpM $ do
76+useCon md name = Generate $ do
77 lift $ tell $ S.singleton $ ModuleName md
77 lift $ tell $ S.singleton $ ModuleName md
78 return $ Qual (ModuleName md) name
78 return $ Qual (ModuleName md) name
79
79
80-- | Use the value of a variable with the given name.
80-- | Use the value of a variable with the given name.
81useVar :: Name -> ExpG t
81useVar :: Name -> ExpG t
82−useVar name = return $ Var $ UnQual name
82+useVar name = return $ Expression $ Var $ UnQual name
83
83
84-- | Generate a new unique variable name with the given prefix. Note that this new variable name
84-- | Generate a new unique variable name with the given prefix. Note that this new variable name
85-- is only unique relative to other variable names generated by this function.
85-- is only unique relative to other variable names generated by this function.
86−newName :: String -> ExpM t Name
86+newName :: String -> Generate Name
87−newName pref = ExpM $ do
87+newName pref = Generate $ do
88 i <- get <* modify succ
88 i <- get <* modify succ
89 return $ Ident $ pref ++ show i
89 return $ Ident $ pref ++ show i
90
90
91−-- | This type family can be used to get the type associated with some expression.
92−type family ExpType a :: *
93−type instance ExpType (ExpM t a) = t
94−
95-- | Generate a expression from a haskell value.
91-- | Generate a expression from a haskell value.
96class GenExp t where
92class GenExp t where
97 type GenExpType t :: *
93 type GenExpType t :: *
@@ -103,36 +99,43 @@ instance GenExp (ExpG a) where
103 type GenExpType (ExpG a) = a
99 type GenExpType (ExpG a) = a
104 expr = id
100 expr = id
105
101
102+instance GenExp (Expression t) where
103+ type GenExpType (Expression t) = t
104+ expr = return
105+
106instance GenExp Char where
106instance GenExp Char where
107 type GenExpType Char = Char
107 type GenExpType Char = Char
108− expr = return . Lit . Char
108+ expr = return . Expression . Lit . Char
109
109
110instance GenExp Integer where
110instance GenExp Integer where
111 type GenExpType Integer = Integer
111 type GenExpType Integer = Integer
112− expr = return . Lit . Int
112+ expr = return . Expression . Lit . Int
113
113
114instance GenExp Rational where
114instance GenExp Rational where
115 type GenExpType Rational = Rational
115 type GenExpType Rational = Rational
116− expr = return . Lit . Frac
116+ expr = return . Expression . Lit . Frac
117
117
118instance GenExp a => GenExp [a] where
118instance GenExp a => GenExp [a] where
119 type GenExpType [a] = [GenExpType a]
119 type GenExpType [a] = [GenExpType a]
120− expr = ExpM . fmap List . mapM (unExpM . expr)
120+ expr = Generate . fmap (Expression . List . map runExpression) . mapM (unGenerate . expr)
121
121
122instance GenExp x => GenExp (ExpG a -> x) where
122instance GenExp x => GenExp (ExpG a -> x) where
123 type GenExpType (ExpG a -> x) = a -> GenExpType x
123 type GenExpType (ExpG a -> x) = a -> GenExpType x
124 expr f = do
124 expr f = do
125 pvarName <- newName "pvar_"
125 pvarName <- newName "pvar_"
126− body <- unsafeCoerceE $ expr $ f $ return $ Var $ UnQual pvarName
126+ body <- expr $ f $ return $ Expression $ Var $ UnQual pvarName
127− return $ Lambda noLoc [PVar pvarName] body
127+ return $ Expression $ Lambda noLoc [PVar pvarName] $ runExpression body
128
128
129--------------------------------------------------------------------------------
129--------------------------------------------------------------------------------
130-- Apply functions
130-- Apply functions
131
131
132+
132-- | Apply a function in a haskell expression to a value.
133-- | Apply a function in a haskell expression to a value.
133applyE :: ExpG (a -> b) -> ExpG a -> ExpG b
134applyE :: ExpG (a -> b) -> ExpG a -> ExpG b
134−applyE a b = unsafeCoerceE $ liftM (foldl1 App) $ sequence [ce a,ce b]
135+applyE a b = wrap $ liftM (foldl1 App) $ sequence [unwrap a, unwrap b]
135− where ce = unsafeCoerceE
136+ where wrap = fmap Expression
137+ unwrap = fmap runExpression
138+
136
139
137-- | Operator for 'applyE'.
140-- | Operator for 'applyE'.
138(<>$) :: ExpG (a -> b) -> ExpG a -> ExpG b
141(<>$) :: ExpG (a -> b) -> ExpG a -> ExpG b
@@ -142,28 +145,33 @@ infixl 1 <>$
142
145
143-- | ApplyE for 2 arguments
146-- | ApplyE for 2 arguments
144applyE2 :: ExpG (a -> b -> c) -> ExpG a -> ExpG b -> ExpG c
147applyE2 :: ExpG (a -> b -> c) -> ExpG a -> ExpG b -> ExpG c
145−applyE2 a b c = unsafeCoerceE $ liftM (foldl1 App) $ sequence [ce a,ce b,ce c]
148+applyE2 a b c = wrap $ liftM (foldl1 App) $ sequence [unwrap a,unwrap b,unwrap c]
146− where ce = unsafeCoerceE
149+ where wrap = fmap Expression
150+ unwrap = fmap runExpression
147
151
148-- | Apply a function to 3 arguments
152-- | Apply a function to 3 arguments
149applyE3 :: ExpG (a -> b -> c -> d) -> ExpG a -> ExpG b -> ExpG c -> ExpG d
153applyE3 :: ExpG (a -> b -> c -> d) -> ExpG a -> ExpG b -> ExpG c -> ExpG d
150−applyE3 a b c d = unsafeCoerceE $ liftM (foldl1 App) $ sequence [ce a,ce b,ce c,ce d]
154+applyE3 a b c d = wrap $ liftM (foldl1 App) $ sequence [unwrap a,unwrap b,unwrap c,unwrap d]
151− where ce = unsafeCoerceE
155+ where wrap = fmap Expression
156+ unwrap = fmap runExpression
152
157
153-- | Apply a function to 4 arguments
158-- | Apply a function to 4 arguments
154applyE4 :: ExpG (a -> b -> c -> d -> e) -> ExpG a -> ExpG b -> ExpG c -> ExpG d -> ExpG e
159applyE4 :: ExpG (a -> b -> c -> d -> e) -> ExpG a -> ExpG b -> ExpG c -> ExpG d -> ExpG e
155−applyE4 a b c d e = unsafeCoerceE $ liftM (foldl1 App) $ sequence [ce a,ce b,ce c,ce d,ce e]
160+applyE4 a b c d e = wrap $ liftM (foldl1 App) $ sequence [unwrap a,unwrap b,unwrap c,unwrap d,unwrap e]
156− where ce = unsafeCoerceE
161+ where wrap = fmap Expression
162+ unwrap = fmap runExpression
157
163
158-- | Apply a function to 5 arguments
164-- | Apply a function to 5 arguments
159applyE5 :: ExpG (a -> b -> c -> d -> e -> f) -> ExpG a -> ExpG b -> ExpG c -> ExpG d -> ExpG e -> ExpG f
165applyE5 :: ExpG (a -> b -> c -> d -> e -> f) -> ExpG a -> ExpG b -> ExpG c -> ExpG d -> ExpG e -> ExpG f
160−applyE5 a b c d e f = unsafeCoerceE $ liftM (foldl1 App) $ sequence [ce a,ce b,ce c,ce d,ce e,ce f]
166+applyE5 a b c d e f = wrap $ liftM (foldl1 App) $ sequence [unwrap a,unwrap b,unwrap c,unwrap d,unwrap e,unwrap f]
161− where ce = unsafeCoerceE
167+ where wrap = fmap Expression
168+ unwrap = fmap runExpression
162
169
163-- | Apply a function to 6 arguments
170-- | Apply a function to 6 arguments
164applyE6 :: ExpG (a -> b -> c -> d -> e -> f -> g) -> ExpG a -> ExpG b -> ExpG c -> ExpG d -> ExpG e -> ExpG f -> ExpG g
171applyE6 :: ExpG (a -> b -> c -> d -> e -> f -> g) -> ExpG a -> ExpG b -> ExpG c -> ExpG d -> ExpG e -> ExpG f -> ExpG g
165−applyE6 a b c d e f g = unsafeCoerceE $ liftM (foldl1 App) $ sequence [ce a,ce b,ce c,ce d,ce e,ce f,ce g]
172+applyE6 a b c d e f g = wrap $ liftM (foldl1 App) $ sequence [unwrap a,unwrap b,unwrap c,unwrap d,unwrap e,unwrap f,unwrap g]
166− where ce = unsafeCoerceE
173+ where wrap = fmap Expression
174+ unwrap = fmap runExpression
167
175
168--------------------------------------------------------------------------------
176--------------------------------------------------------------------------------
169-- Generate modules
177-- Generate modules
@@ -180,7 +188,7 @@ data FunRef t = FunRef Name
180
188
181instance GenExp (FunRef t) where
189instance GenExp (FunRef t) where
182 type GenExpType (FunRef t) = t
190 type GenExpType (FunRef t) = t
183− expr (FunRef n) = return $ Var $ UnQual n
191+ expr (FunRef n) = return $ Expression $ Var $ UnQual n
184
192
185-- | Generate a ExportSpec for a given function item.
193-- | Generate a ExportSpec for a given function item.
186exportFun :: FunRef t -> ExportSpec
194exportFun :: FunRef t -> ExportSpec
@@ -189,8 +197,8 @@ exportFun (FunRef name) = EVar (UnQual name)
189-- | Add a declaration to the module. Return a reference to it that can be used to either apply the function to some values or export it.
197-- | Add a declaration to the module. Return a reference to it that can be used to either apply the function to some values or export it.
190addDecl :: Name -> ExpG t -> ModuleM (FunRef t)
198addDecl :: Name -> ExpG t -> ModuleM (FunRef t)
191addDecl name e = ModuleM $ do
199addDecl name e = ModuleM $ do
192− let (body, mods) = runExpM e
200+ let (body, mods) = runGenerate e
193− tell (mods, [FunBind [Match noLoc name [] Nothing (UnGuardedRhs body) $ BDecls []]])
201+ tell (mods, [FunBind [Match noLoc name [] Nothing (UnGuardedRhs $ runExpression body) $ BDecls []]])
194 return $ FunRef name
202 return $ FunRef name
195
203
196-- | Extract the Module from a module generator.
204-- | Extract the Module from a module generator.
src/Language/Haskell/Generate/PreludeDef.hs+8−8
@@ -6,7 +6,7 @@
6module Language.Haskell.Generate.PreludeDef where
6module Language.Haskell.Generate.PreludeDef where
7
7
8import Language.Haskell.Exts.Syntax
8import Language.Haskell.Exts.Syntax
9−import Language.Haskell.Generate.Base
9+import Language.Haskell.Generate.Monad
10import Language.Haskell.Generate.TH
10import Language.Haskell.Generate.TH
11
11
12--------------------------------------------------------------------------------
12--------------------------------------------------------------------------------
@@ -66,22 +66,22 @@ fmap concat $ mapM declareNamedSymbol
66(<>.) a b = dot' <>$ a <>$ b
66(<>.) a b = dot' <>$ a <>$ b
67
67
68tuple0 :: ExpG ()
68tuple0 :: ExpG ()
69−tuple0 = return $ Var $ Special UnitCon
69+tuple0 = returnE $ Var $ Special UnitCon
70
70
71tuple2 :: ExpG (a -> b -> (a,b))
71tuple2 :: ExpG (a -> b -> (a,b))
72−tuple2 = return $ Var $ Special $ TupleCon Boxed 2
72+tuple2 = returnE $ Var $ Special $ TupleCon Boxed 2
73
73
74tuple3 :: ExpG (a -> b -> c -> (a,b,c))
74tuple3 :: ExpG (a -> b -> c -> (a,b,c))
75−tuple3 = return $ Var $ Special $ TupleCon Boxed 3
75+tuple3 = returnE $ Var $ Special $ TupleCon Boxed 3
76
76
77tuple4 :: ExpG (a -> b -> c -> d -> (a,b,c,d))
77tuple4 :: ExpG (a -> b -> c -> d -> (a,b,c,d))
78−tuple4 = return $ Var $ Special $ TupleCon Boxed 4
78+tuple4 = returnE $ Var $ Special $ TupleCon Boxed 4
79
79
80tuple5 :: ExpG (a -> b -> c -> d -> (a,b,c,d,e))
80tuple5 :: ExpG (a -> b -> c -> d -> (a,b,c,d,e))
81−tuple5 = return $ Var $ Special $ TupleCon Boxed 5
81+tuple5 = returnE $ Var $ Special $ TupleCon Boxed 5
82
82
83cons :: ExpG (a -> [a] -> [a])
83cons :: ExpG (a -> [a] -> [a])
84−cons = return $ Var $ Special Cons
84+cons = returnE $ Var $ Special Cons
85
85
86instance Num t => Num (ExpG t) where
86instance Num t => Num (ExpG t) where
87 a + b = add' <>$ a <>$ b
87 a + b = add' <>$ a <>$ b
@@ -89,6 +89,6 @@ instance Num t => Num (ExpG t) where
89 a * b = mult' <>$ a <>$ b
89 a * b = mult' <>$ a <>$ b
90 negate a = negate' <>$ a
90 negate a = negate' <>$ a
91 abs a = abs' <>$ a
91 abs a = abs' <>$ a
92− fromInteger a = return $ Lit $ Int a
92+ fromInteger a = returnE $ Lit $ Int a
93 signum a = signum' <>$ a
93 signum a = signum' <>$ a
94
94
src/Language/Haskell/Generate/TH.hs+6−2
@@ -10,7 +10,7 @@ module Language.Haskell.Generate.TH
10
10
11import Data.Char
11import Data.Char
12import Language.Haskell.Exts.Syntax hiding (Name)
12import Language.Haskell.Exts.Syntax hiding (Name)
13−import Language.Haskell.Generate.Base hiding (Name)
13+import Language.Haskell.Generate.Monad hiding (Name)
14import Language.Haskell.TH
14import Language.Haskell.TH
15import Language.Haskell.TH.Syntax
15import Language.Haskell.TH.Syntax
16
16
@@ -36,9 +36,13 @@ declareNamedThing (thing, name, thingClass) = do
36 [| useValue $(lift md) $ $(conE thingClass) $(lift $ nameBase thing) |]
36 [| useValue $(lift md) $ $(conE thingClass) $(lift $ nameBase thing) |]
37 ]
37 ]
38
38
39− where overQuantifiedType f (ForallT bnds ctx t) = ForallT bnds ctx $ overQuantifiedType f t
39+ where overQuantifiedType f (ForallT bnds ctx t) = ForallT (map removeKind bnds) ctx $ overQuantifiedType f t
40 overQuantifiedType f x = f x
40 overQuantifiedType f x = f x
41
41
42+ removeKind :: TyVarBndr -> TyVarBndr
43+ removeKind (KindedTV n _) = PlainTV n
44+ removeKind x = x
45+
42-- | Declare a symbol, using the given name for the definition.
46-- | Declare a symbol, using the given name for the definition.
43declareNamedSymbol :: (Name, String) -> DecsQ
47declareNamedSymbol :: (Name, String) -> DecsQ
44declareNamedSymbol (func, name) = declareNamedThing (func, name, 'Symbol)
48declareNamedSymbol (func, name) = declareNamedThing (func, name, 'Symbol)