git.iko.soy/haskell-generate
on master help sign in
10 files changed+240−77
since splitsnapshots
unifiedsplit
.travis.yml+6−4 LICENSE+1−1 README.md+99−1 haskell-generate.cabal+11−7 src/Language/Haskell/Generate.hs+2−1 src/Language/Haskell/Generate/Expression.hs+12 src/Language/Haskell/Generate/Base.hs → src/Language/Haskell/Generate/Monad.hs+93−51 src/Language/Haskell/Generate/PreludeDef.hs+9−8 src/Language/Haskell/Generate/TH.hs+6−2 tests/doctests.hsc+1−2
.travis.yml+6−4
@@ -1,17 +1,19 @@
11env:
22 - GHCVER=7.4.2 CABALVER=1.16
33 - GHCVER=7.6.3 CABALVER=1.18
4− - GHCVER=head CABALVER=1.18
4+ - GHCVER=7.8.3 CABALVER=1.20
5+ - GHCVER=7.10.2 CABALVER=1.22
6+ - GHCVER=head CABALVER=1.22
57
68before_install:
79 - sudo add-apt-repository -y ppa:hvr/ghc
810 - sudo apt-get update
911 - sudo apt-get install cabal-install-$CABALVER ghc-$GHCVER hlint
12+ - cabal-$CABALVER update
1013 - cabal-$CABALVER install happy -j
1114 - export PATH=/opt/ghc/$GHCVER/bin:~/.cabal/bin:$PATH
1215
1316install:
14− - cabal-$CABALVER update
1517 - cabal-$CABALVER install --only-dependencies --enable-tests --enable-benchmarks -j
1618
1719script:
@@ -20,5 +22,5 @@ script:
2022
2123matrix:
2224 allow_failures:
23− - env: GHCVER=head CABALVER=1.18
24− fast_finish: true
25+ - env: GHCVER=head CABALVER=1.22
26+ fast_finish: true
LICENSE+1−1
@@ -1,4 +1,4 @@
1−Copyright 2013 Benno Fünfstück
1+Copyright 2013-2015 Benno Fünfstück
22
33All rights reserved.
44
README.md+99−1
@@ -1,6 +1,104 @@
11haskell-generate
2−====================
2+================
33
44[![Build Status](https://secure.travis-ci.org/bennofs/haskell-generate.png?branch=master)](http://travis-ci.org/bennofs/haskell-generate)
55
6+## Introduction
67
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.
haskell-generate.cabal+11−7
@@ -1,5 +1,5 @@
11name: haskell-generate
2−version: 0.1
2+version: 0.2.4
33license: BSD3
44category: Code Generation, Language
55cabal-version: >= 1.10
@@ -9,9 +9,13 @@ maintainer: Benno Fünfstück <benno.fuenfstueck@gmail.com>
99stability: experimental
1010homepage: http://github.com/bennofs/haskell-generate/
1111bug-reports: http://github.com/bennofs/haskell-generate/issues
12−copyright: Copyright (C) 2013 Benno Fünfstück
13−synopsis: haskell-generate
14−description: haskell-generate
12+copyright: Copyright (C) 2013-2015 Benno Fünfstück
13+synopsis: Typesafe generation of haskell source code
14+description:
15+ This library provides an interface to generate haskell source code, verifying at compile time
16+ that the resulting code typechecks.
17+ See <https://github.com/bennofs/haskell-generate haskell-generate> for an
18+ introduction explaining how to use the library.
1519build-type: Custom
1620
1721extra-source-files:
@@ -37,9 +41,11 @@ library
3741 , template-haskell
3842 exposed-modules:
3943 Language.Haskell.Generate
40− Language.Haskell.Generate.Base
44+ Language.Haskell.Generate.Monad
45+ Language.Haskell.Generate.Expression
4146 Language.Haskell.Generate.TH
4247 Language.Haskell.Generate.PreludeDef
48+ other-extensions: TemplateHaskell
4349
4450test-suite doctests
4551 type: exitcode-stdio-1.0
@@ -51,6 +57,4 @@ test-suite doctests
5157 , doctest >= 0.9.1
5258 , filepath
5359 ghc-options: -Wall -threaded
54− if impl(ghc<7.6.1)
55− ghc-options: -Werror
5660 hs-source-dirs: tests
src/Language/Haskell/Generate.hs+2−1
@@ -2,5 +2,6 @@ module Language.Haskell.Generate
22 ( module X
33 ) where
44
5−import Language.Haskell.Generate.Base as X
5+import Language.Haskell.Exts.Syntax as X
6+import Language.Haskell.Generate.Monad as X
67import 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+93−51
@@ -3,9 +3,11 @@
33{-# LANGUAGE ScopedTypeVariables #-}
44{-# LANGUAGE UndecidableInstances #-}
55{-# LANGUAGE FlexibleInstances #-}
6−module Language.Haskell.Generate.Base
7− ( ExpM(..), ExpG, ExpType
8− , runExpM, newName
6+{-# LANGUAGE CPP #-}
7+module Language.Haskell.Generate.Monad
8+ ( Generate(..), ExpG
9+ , runGenerate, newName
10+ , returnE
911 , useValue, useCon, useVar
1012 , caseE
1113 , applyE, applyE2, applyE3, applyE4, applyE5, applyE6
@@ -19,6 +21,7 @@ module Language.Haskell.Generate.Base
1921 , addDecl
2022 , runModuleM
2123 , generateModule
24+ , generateExp
2225 )
2326 where
2427
@@ -31,32 +34,44 @@ import qualified Data.Set as S
3134import Language.Haskell.Exts.Pretty
3235import Language.Haskell.Exts.SrcLoc
3336import Language.Haskell.Exts.Syntax
37+import Language.Haskell.Generate.Expression
38+
39+import Prelude
3440
3541--------------------------------------------------------------------------------
3642-- Generate expressions
3743
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)
44+-- | This monad keeps track of a counter for generating unique names and the set of modules
45+-- that are needed for the expression.
46+newtype Generate a = Generate { unGenerate :: StateT Integer (Writer (S.Set ModuleName)) a } deriving (Functor, Applicative, Monad)
47+
48+-- | Extract the set of modules and the value from a Generate action.
49+runGenerate :: Generate a -> (a, S.Set ModuleName)
50+runGenerate (Generate a) = runWriter $ evalStateT a 0
4251
43−-- | The ExpG type is a ExpM computation that returns an expression. Usually, this is the end result of a function generating
44−-- a haskell expression
45−type ExpG t = ExpM t Exp
52+-- | This is a type alias for a Generate action that returns an expression of type 't'.
53+type ExpG t = Generate (Expression t)
4654
47−-- | Evaluate a ExpM action, returning the needed modules and the value.
48−runExpM :: ExpM t a -> (a, S.Set ModuleName)
49−runExpM (ExpM expt) = runWriter $ evalStateT expt 0
55+-- | Use a haskell-src-exts Exp as the result of a Generate action.
56+returnE :: Exp -> ExpG t
57+returnE = return . Expression
5058
51−unsafeCoerceE :: ExpM t a -> ExpM t' a
52−unsafeCoerceE (ExpM x) = ExpM x
59+-- | Pretty print the expression generated by a given action.
60+generateExp :: ExpG t -> String
61+generateExp = prettyPrint . runExpression . fst . runGenerate
5362
5463-- | Generate a case expression.
5564caseE :: ExpG x -> [(Pat, ExpG t)] -> ExpG t
5665caseE v alt = do
57− v' <- unsafeCoerceE v
58− alt' <- mapM (\(p,a) -> fmap (\a' -> Alt noLoc p (UnGuardedAlt a') (BDecls [])) a) alt
59− return $ Case v' alt'
66+ v' <- v
67+#if MIN_VERSION_haskell_src_exts(1,17,0)
68+ alt' <- mapM (\(p,a) -> fmap (\a' -> Alt noLoc p (UnGuardedRhs $ runExpression a') Nothing) a) alt
69+#elif MIN_VERSION_haskell_src_exts(1,16,0)
70+ alt' <- mapM (\(p,a) -> fmap (\a' -> Alt noLoc p (UnGuardedRhs $ runExpression a') (BDecls [])) a) alt
71+#else
72+ alt' <- mapM (\(p,a) -> fmap (\a' -> Alt noLoc p (UnGuardedAlt $ runExpression a') (BDecls [])) a) alt
73+#endif
74+ return $ Expression $ Case (runExpression v') alt'
6075
6176-- | Import a function from a module. This function is polymorphic in the type of the resulting expression,
6277-- you should probably only use this function to define type-restricted specializations.
@@ -67,32 +82,37 @@ caseE v alt = do
6782-- > addInt = useValue "Prelude" $ Symbol "+"
6883--
6984useValue :: String -> Name -> ExpG a
70−useValue md name = ExpM $ do
85+useValue md name = Generate $ do
7186 lift $ tell $ S.singleton $ ModuleName md
72− return $ Var $ Qual (ModuleName md) name
87+ return $ Expression $ Var $ Qual (ModuleName md) name
7388
7489-- | Import a value constructor from a module. Returns the qualified name of the constructor.
75−useCon :: String -> Name -> ExpM t QName
76−useCon md name = ExpM $ do
90+useCon :: String -> Name -> Generate QName
91+useCon md name = Generate $ do
7792 lift $ tell $ S.singleton $ ModuleName md
7893 return $ Qual (ModuleName md) name
7994
8095-- | Use the value of a variable with the given name.
8196useVar :: Name -> ExpG t
82−useVar name = return $ Var $ UnQual name
97+useVar name = return $ Expression $ Var $ UnQual name
8398
8499-- | Generate a new unique variable name with the given prefix. Note that this new variable name
85100-- is only unique relative to other variable names generated by this function.
86−newName :: String -> ExpM t Name
87−newName pref = ExpM $ do
101+newName :: String -> Generate Name
102+newName pref = Generate $ do
88103 i <- get <* modify succ
89104 return $ Ident $ pref ++ show i
90105
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.
106+-- | Generate a expression from a haskell value. This can for example be used to create lambdas:
107+--
108+-- >>> putStrLn $ generateExp $ expr (\x f -> f <>$ x)
109+-- \ pvar_0 -> \ pvar_1 -> pvar_1 pvar_0
110+--
111+-- Or string literals:
112+--
113+-- >>> putStrLn $ generateExp $ expr "I'm a string!"
114+-- ['I', '\'', 'm', ' ', 'a', ' ', 's', 't', 'r', 'i', 'n', 'g', '!']
115+--
96116class GenExp t where
97117 type GenExpType t :: *
98118
@@ -103,36 +123,41 @@ instance GenExp (ExpG a) where
103123 type GenExpType (ExpG a) = a
104124 expr = id
105125
126+instance GenExp (Expression t) where
127+ type GenExpType (Expression t) = t
128+ expr = return
129+
106130instance GenExp Char where
107131 type GenExpType Char = Char
108− expr = return . Lit . Char
132+ expr = return . Expression . Lit . Char
109133
110134instance GenExp Integer where
111135 type GenExpType Integer = Integer
112− expr = return . Lit . Int
136+ expr = return . Expression . Lit . Int
113137
114138instance GenExp Rational where
115139 type GenExpType Rational = Rational
116− expr = return . Lit . Frac
140+ expr = return . Expression . Lit . Frac
117141
118142instance GenExp a => GenExp [a] where
119143 type GenExpType [a] = [GenExpType a]
120− expr = ExpM . fmap List . mapM (unExpM . expr)
144+ expr = Generate . fmap (Expression . List . map runExpression) . mapM (unGenerate . expr)
121145
122146instance GenExp x => GenExp (ExpG a -> x) where
123147 type GenExpType (ExpG a -> x) = a -> GenExpType x
124148 expr f = do
125149 pvarName <- newName "pvar_"
126− body <- unsafeCoerceE $ expr $ f $ return $ Var $ UnQual pvarName
127− return $ Lambda noLoc [PVar pvarName] body
150+ body <- expr $ f $ return $ Expression $ Var $ UnQual pvarName
151+ return $ Expression $ Lambda noLoc [PVar pvarName] $ runExpression body
128152
129153--------------------------------------------------------------------------------
130154-- Apply functions
131155
132156-- | Apply a function in a haskell expression to a value.
133157applyE :: ExpG (a -> b) -> ExpG a -> ExpG b
134−applyE a b = unsafeCoerceE $ liftM (foldl1 App) $ sequence [ce a,ce b]
135− where ce = unsafeCoerceE
158+applyE a b = wrap $ liftM (foldl1 App) $ sequence [unwrap a, unwrap b]
159+ where wrap = fmap Expression
160+ unwrap = fmap runExpression
136161
137162-- | Operator for 'applyE'.
138163(<>$) :: ExpG (a -> b) -> ExpG a -> ExpG b
@@ -142,28 +167,33 @@ infixl 1 <>$
142167
143168-- | ApplyE for 2 arguments
144169applyE2 :: 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]
146− where ce = unsafeCoerceE
170+applyE2 a b c = wrap $ liftM (foldl1 App) $ sequence [unwrap a,unwrap b,unwrap c]
171+ where wrap = fmap Expression
172+ unwrap = fmap runExpression
147173
148174-- | Apply a function to 3 arguments
149175applyE3 :: 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]
151− where ce = unsafeCoerceE
176+applyE3 a b c d = wrap $ liftM (foldl1 App) $ sequence [unwrap a,unwrap b,unwrap c,unwrap d]
177+ where wrap = fmap Expression
178+ unwrap = fmap runExpression
152179
153180-- | Apply a function to 4 arguments
154181applyE4 :: 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]
156− where ce = unsafeCoerceE
182+applyE4 a b c d e = wrap $ liftM (foldl1 App) $ sequence [unwrap a,unwrap b,unwrap c,unwrap d,unwrap e]
183+ where wrap = fmap Expression
184+ unwrap = fmap runExpression
157185
158186-- | Apply a function to 5 arguments
159187applyE5 :: 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]
161− where ce = unsafeCoerceE
188+applyE5 a b c d e f = wrap $ liftM (foldl1 App) $ sequence [unwrap a,unwrap b,unwrap c,unwrap d,unwrap e,unwrap f]
189+ where wrap = fmap Expression
190+ unwrap = fmap runExpression
162191
163192-- | Apply a function to 6 arguments
164193applyE6 :: 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]
166− where ce = unsafeCoerceE
194+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]
195+ where wrap = fmap Expression
196+ unwrap = fmap runExpression
167197
168198--------------------------------------------------------------------------------
169199-- Generate modules
@@ -180,23 +210,35 @@ data FunRef t = FunRef Name
180210
181211instance GenExp (FunRef t) where
182212 type GenExpType (FunRef t) = t
183− expr (FunRef n) = return $ Var $ UnQual n
213+ expr (FunRef n) = return $ Expression $ Var $ UnQual n
184214
185215-- | Generate a ExportSpec for a given function item.
186216exportFun :: FunRef t -> ExportSpec
217+#if MIN_VERSION_haskell_src_exts(1,16,0) && !MIN_VERSION_haskell_src_exts(1,17,0)
218+exportFun (FunRef name) = EVar NoNamespace (UnQual name)
219+#else
187220exportFun (FunRef name) = EVar (UnQual name)
221+#endif
188222
189223-- | 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.
190224addDecl :: Name -> ExpG t -> ModuleM (FunRef t)
191225addDecl name e = ModuleM $ do
192− let (body, mods) = runExpM e
193− tell (mods, [FunBind [Match noLoc name [] Nothing (UnGuardedRhs body) $ BDecls []]])
226+ let (body, mods) = runGenerate e
227+#if MIN_VERSION_haskell_src_exts(1,17,0)
228+ tell (mods, [FunBind [Match noLoc name [] Nothing (UnGuardedRhs $ runExpression body) Nothing]])
229+#else
230+ tell (mods, [FunBind [Match noLoc name [] Nothing (UnGuardedRhs $ runExpression body) $ BDecls []]])
231+#endif
194232 return $ FunRef name
195233
196234-- | Extract the Module from a module generator.
197235runModuleM :: ModuleG -> String -> Module
198236runModuleM (ModuleM act) name =
237+#if MIN_VERSION_haskell_src_exts(1,16,0)
238+ Module noLoc (ModuleName name) [] Nothing export (map (\md -> ImportDecl noLoc md True False False Nothing Nothing Nothing) $ S.toList imps) decls
239+#else
199240 Module noLoc (ModuleName name) [] Nothing export (map (\md -> ImportDecl noLoc md True False Nothing Nothing Nothing) $ S.toList imps) decls
241+#endif
200242 where (export, (imps, decls)) = runWriter act
201243
202244-- | Generate the source code for a module.
src/Language/Haskell/Generate/PreludeDef.hs+9−8
@@ -6,7 +6,7 @@
66module Language.Haskell.Generate.PreludeDef where
77
88import Language.Haskell.Exts.Syntax
9−import Language.Haskell.Generate.Base
9+import Language.Haskell.Generate.Monad
1010import Language.Haskell.Generate.TH
1111
1212--------------------------------------------------------------------------------
@@ -60,28 +60,29 @@ fmap concat $ mapM declareNamedSymbol
6060 , ('(++), "append'")
6161 , ('(!!), "index'")
6262 , ('(==), "equal'")
63+ , ('(/=), "notequal'")
6364 ]
6465
6566(<>.) :: ExpG (b -> c) -> ExpG (a -> b) -> ExpG (a -> c)
6667(<>.) a b = dot' <>$ a <>$ b
6768
6869tuple0 :: ExpG ()
69−tuple0 = return $ Var $ Special UnitCon
70+tuple0 = returnE $ Var $ Special UnitCon
7071
7172tuple2 :: ExpG (a -> b -> (a,b))
72−tuple2 = return $ Var $ Special $ TupleCon Boxed 2
73+tuple2 = returnE $ Var $ Special $ TupleCon Boxed 2
7374
7475tuple3 :: ExpG (a -> b -> c -> (a,b,c))
75−tuple3 = return $ Var $ Special $ TupleCon Boxed 3
76+tuple3 = returnE $ Var $ Special $ TupleCon Boxed 3
7677
7778tuple4 :: ExpG (a -> b -> c -> d -> (a,b,c,d))
78−tuple4 = return $ Var $ Special $ TupleCon Boxed 4
79+tuple4 = returnE $ Var $ Special $ TupleCon Boxed 4
7980
8081tuple5 :: ExpG (a -> b -> c -> d -> (a,b,c,d,e))
81−tuple5 = return $ Var $ Special $ TupleCon Boxed 5
82+tuple5 = returnE $ Var $ Special $ TupleCon Boxed 5
8283
8384cons :: ExpG (a -> [a] -> [a])
84−cons = return $ Var $ Special Cons
85+cons = returnE $ Var $ Special Cons
8586
8687instance Num t => Num (ExpG t) where
8788 a + b = add' <>$ a <>$ b
@@ -89,6 +90,6 @@ instance Num t => Num (ExpG t) where
8990 a * b = mult' <>$ a <>$ b
9091 negate a = negate' <>$ a
9192 abs a = abs' <>$ a
92− fromInteger a = return $ Lit $ Int a
93+ fromInteger a = returnE $ Lit $ Int a
9394 signum a = signum' <>$ a
9495
src/Language/Haskell/Generate/TH.hs+6−2
@@ -10,7 +10,7 @@ module Language.Haskell.Generate.TH
1010
1111import Data.Char
1212import Language.Haskell.Exts.Syntax hiding (Name)
13−import Language.Haskell.Generate.Base hiding (Name)
13+import Language.Haskell.Generate.Monad hiding (Name)
1414import Language.Haskell.TH
1515import Language.Haskell.TH.Syntax
1616
@@ -36,9 +36,13 @@ declareNamedThing (thing, name, thingClass) = do
3636 [| useValue $(lift md) $ $(conE thingClass) $(lift $ nameBase thing) |]
3737 ]
3838
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
4040 overQuantifiedType f x = f x
4141
42+ removeKind :: TyVarBndr -> TyVarBndr
43+ removeKind (KindedTV n _) = PlainTV n
44+ removeKind x = x
45+
4246-- | Declare a symbol, using the given name for the definition.
4347declareNamedSymbol :: (Name, String) -> DecsQ
4448declareNamedSymbol (func, name) = declareNamedThing (func, name, 'Symbol)
tests/doctests.hsc+1−2
@@ -20,18 +20,17 @@ import Data.List
2020import System.Directory
2121import System.FilePath
2222import Test.DocTest
23+import Prelude
2324
2425##ifdef mingw32_HOST_ARCH
2526##ifdef i386_HOST_ARCH
2627##define USE_CP
27−import Control.Applicative
2828import Control.Exception
2929import Foreign.C.Types
3030foreign import stdcall "windows.h SetConsoleCP" c_SetConsoleCP :: CUInt -> IO Bool
3131foreign import stdcall "windows.h GetConsoleCP" c_GetConsoleCP :: IO CUInt
3232##elif defined(x86_64_HOST_ARCH)
3333##define USE_CP
34−import Control.Applicative
3534import Control.Exception
3635import Foreign.C.Types
3736foreign import ccall "windows.h SetConsoleCP" c_SetConsoleCP :: CUInt -> IO Bool