Use new TH.TypeLib for vectorTH
[matthijs/master-project/support/tfvec.git] / Language / Haskell / TH / TypeLib.hs
1 {-# LANGUAGE TemplateHaskell #-}
2 -----------------------------------------------------------------------------
3 -- |
4 -- Module      :  Language.Haskell.TH.TypeLib
5 -- Copyright   :  (c) SAM Group, KTH/ICT/ECS 2007-2008
6 -- License     :  BSD-style (see the file LICENSE)
7 -- 
8 -- Maintainer  :  forsyde-dev@ict.kth.se
9 -- Stability   :  experimental
10 -- Portability :  portable
11 --
12 -- This module provides basic functions related to Template-Haskell's 'Type'.
13 -- 
14 -----------------------------------------------------------------------------
15 module Language.Haskell.TH.TypeLib 
16  (reAppT,
17   dynTHType,
18   thTypeOf,
19   typeRep2Type,
20   tyCon2Type) 
21  where
22
23 import Data.Dynamic
24 import Data.Typeable
25 import Language.Haskell.TH
26 import Language.Haskell.TH.Lib
27 import Text.Regex.Posix ((=~))
28
29 -- | Rebuild a type out of a constructor, its argument types and its context
30 --   (inverse of 'unAppT')
31 reAppT :: (TypeQ, [TypeQ])  -- ^ (Constructor, type arguments, context)
32        -> TypeQ                     -- ^ resulting 'Type'
33 -- Monomorphic types
34 reAppT (cons, args) = foldl1 appT (cons:args)
35
36 -------------------------------------------------------------------
37 -- Transforming Data.Typeable.TypeRep into Language.Haskell.TH.Type
38 -------------------------------------------------------------------  
39
40 -- | Obtain the Template Haskel type of a dynamic object
41 dynTHType :: Dynamic -> TypeQ
42 dynTHType = typeRep2Type . dynTypeRep
43
44 -- | Give the template haskell 'Type' of a Typeable object
45 thTypeOf :: Typeable a => a -> TypeQ
46 thTypeOf = typeRep2Type . typeOf
47
48 -- | Translate a 'TypeRep' to a Template Haskell 'Type'
49 typeRep2Type :: TypeRep -> TypeQ
50 typeRep2Type rep = let (con, reps) = splitTyConApp rep
51   in reAppT (tyCon2Type con, map typeRep2Type reps)
52  
53 -- | Gives the corresponding Template Haskell 'Type' of a 'TyCon'
54 tyCon2Type :: TyCon -> TypeQ
55 tyCon2Type = tyConStr2Type . tyConString
56
57 ----------------------------
58 -- Internal Helper Functions
59 ----------------------------
60
61 -- | transfrom a Typeable type constructor to a Template Haskell Type
62 tyConStr2Type :: String -> TypeQ
63 -- NOTE: The tyCon strings of basic types are not qualified and buggy in 
64 -- some cases.
65 -- See http://hackage.haskell.org/trac/ghc/ticket/1841
66 -- FIXME: update this function whenever the bug is fixed
67 -- FIXME FIXME: This code is incorrect:
68 -- mkName doesn't generate global names! ''Maybe /= mkName "Data.Maybe.Maybe"
69 -- in addition global names contain a packagename which cannot be guessed from
70 -- the type representation.
71 tyConStr2Type "->" = arrowT
72 tyConStr2Type  tupStr | tupStr =~ "^,+$" = 
73  conT (mkName $ "Data.Tuple.(" ++ tupStr ++ ")")   
74 tyConStr2Type str  = conT $ mkName str
75
76 tyVarToName :: TyVarBndr -> Name
77 tyVarToName tyvar = name
78   where
79     name = case tyvar of
80       (PlainTV n) -> n
81       (KindedTV n _) -> n