{-# Language TemplateHaskell, GADTs #-} module Main (main) where import Control.Monad import Language.Haskell.TH import Language.Haskell.TH.Datatype type Gadt1Int = Gadt1 Int data Gadt1 a where Gadtc1 :: Int -> Gadt1Int Gadtc2 :: (a,a) -> Gadt1 a data Adt1 a b = Adtc1 (a,b) | Bool `Adtc2` Int data Gadtrec1 a where Gadtrecc1 :: { gadtrec1a :: a, gadtrec1b :: b } -> Gadtrec1 (a,b) return [] -- segment type declarations above from refiy below main :: IO () main = do adt1Test gadt1Test gadtrec1Test adt1Test :: IO () adt1Test = $(do info <- reifyDatatype ''Adt1 let [a,b] = freeVariables (datatypeVars info) [c1,c2] = datatypeCons info unless (datatypeName info == ''Adt1) (fail "bad name adt1") unless (datatypeVariant info == Datatype) (fail "bad variant adt1") unless (c1 == ConstructorInfo 'Adtc1 [] [] [AppT (AppT (TupleT 2) (VarT a)) (VarT b)] NormalConstructor) (fail "Bad adtc1") unless (c2 == ConstructorInfo 'Adtc2 [] [] [ConT ''Bool, ConT ''Int] NormalConstructor) (fail "Bad adtc2") [| putStrLn "Adt1 tests passed" |] ) gadt1Test :: IO () gadt1Test = $(do info <- reifyDatatype ''Gadt1 let [a] = freeVariables (datatypeVars info) [c1,c2] = datatypeCons info unless (c1 == ConstructorInfo 'Gadtc1 [] [equalPred (VarT a) (ConT ''Int)] [ConT ''Int] NormalConstructor) (fail ("bad Gadtc1 " ++ show c1)) unless (c2 == ConstructorInfo 'Gadtc2 [] [] [AppT (AppT (TupleT 2) (VarT a)) (VarT a)] NormalConstructor) (fail ("bad Gadtc2 " ++ show c2)) [| putStrLn "Gadt1 tests passed" |] ) gadtrec1Test :: IO () gadtrec1Test = $(do info <- reifyDatatype ''Gadtrec1 let [a] = freeVariables (datatypeVars info) [c] = datatypeCons info [v1,v2] = constructorVars c expectedCxt = [equalPred (VarT a) (AppT (AppT (TupleT 2) (VarT (tvName v1))) (VarT (tvName v2)))] unless (c == ConstructorInfo 'Gadtrecc1 [v1,v2] expectedCxt [VarT (tvName v1), VarT (tvName v2)] (RecordConstructor [ 'gadtrec1a, 'gadtrec1b ])) (fail ("bad constructor for gadtrec1" ++ show c)) [| putStrLn "Gadtrecc1 tests" |] )