{-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE RankNTypes #-} {-# LANGUAGE KindSignatures #-} {-# LANGUAGE TypeFamilies #-} {-# LANGUAGE CPP #-} import Language.Haskell.TH.Datatype.TyVarBndr import Language.Haskell.TH.ExpandSyns import Language.Haskell.TH import Util import Types main :: IO () main = do putStrLn "Basic test..." $(mkTest [t| forall a. Show a => a -> ForAll [] -> (Int,ApplyToInteger []) |] -- GHC 7.8 always seems to consider the body of 'ForallT' to have a 'PlainTV', -- whereas it always has a 'KindedTV' with GHC 7.10 (in both cases, it doesn't appear -- to matter whether the definition of 'ForAll' is actually written with a kind signature). #if MIN_VERSION_template_haskell(2,10,0) [t| forall a. Show a => a -> (forall (x :: *). [] x) -> (Int,[] Integer) |] #else [t| forall a. Show a => a -> (forall x. [] x) -> (Int,[] Integer) |] #endif ) putStrLn "Variable capture avoidance test..." $(let -- See comment about 'PlainTV'/'KindedTV' above #if MIN_VERSION_template_haskell(2,10,0) y_0 = kindedTVSpecified (mkName "y_0") StarT #else y_0 = plainTVSpecified (mkName "y_0") #endif expectedExpansion = forallT [y_0] (cxt []) (conT ''Either `appT` varT' "y" `appT` varT' "y_0" --> conT ''Int) -- the naive (and wrong) result would be: -- forall y. (forall y. Either y y -> Int) in mkTest (forallT'' ["y"] (conT' "E" `appT` varT' "y")) (forallT'' ["y"] expectedExpansion)) putStrLn "Testing that it doesn't crash on type families (expanding them is not supported yet)" $(let t = [t| (DF1 Int, TF1 Int, AT1 Int) |] in mkTest t t) putStrLn "Testing that the args of type family applications are handled" $(mkTest [t| (DF1 Int', TF1 Int', AT1 Int') |] [t| (DF1 Int, TF1 Int, AT1 Int) |]) putStrLn "Higher-kinded synonym" $(mkTest [t| Either' (ListOf Int') (ListOf Char) |] [t| Either [Int] [Char] |]) putStrLn "Nested" $(mkTest [t| Int'' |] [t| Int |]) #if MIN_VERSION_template_haskell(2,8,0) putStrLn "Synonyms in kinds" $(mkTest (sigT (conT ''Int) (ConT ''Id `AppT` StarT)) (sigT (conT ''Int) StarT)) #endif $(do reportWarning "No warning about type families should appear after this line." -- TODO: Automate this test with a custom Quasi instance? _ <- expandSynsWith noWarnTypeFamilies =<< [t| (DF1 Int', TF1 Int', AT1 Int') |] [| return () |])