{-# LANGUAGE DataKinds #-} {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE KindSignatures #-} {-# LANGUAGE FlexibleInstances #-} module T11629 where import Control.Monad import Language.Haskell.TH class C (a :: Bool) class D (a :: (Bool, Bool)) class E (a :: [Bool]) instance C True instance C 'False instance D '(True, False) instance D '(False, True) instance E '[True, False] instance E '[False, True] do let getType (InstanceD _ _ ty _) = ty getType _ = error "getType: only defined for InstanceD" failMsg a ty1 ty2 = fail $ "example " ++ a ++ ": ty1 /= ty2, where\n ty1 = " ++ show ty1 ++ "\n ty2 = " ++ show ty2 withoutSig (ForallT tvs cxt ty) = ForallT tvs cxt (withoutSig ty) withoutSig (AppT ty1 ty2) = AppT (withoutSig ty1) (withoutSig ty2) withoutSig (SigT ty ki) = withoutSig ty withoutSig ty = ty -- test #1: type quotations and reified types should agree. ty1 <- [t| C True |] ty2 <- [t| C 'False |] ClassI _ insts <- reify ''C let [ty1', ty2'] = map getType insts when (ty1 /= ty1') $ failMsg "A" ty1 ty1' when (ty2 /= ty2') $ failMsg "B" ty2 ty2' -- test #2: type quotations and reified types should agree wrt -- promoted tuples. ty3 <- [t| D '(True, False) |] ty4 <- [t| D (False, True) |] ClassI _ insts <- reify ''D let [ty3', ty4'] = map (withoutSig . getType) insts when (ty3 /= ty3') $ failMsg "C" ty3 ty3' -- The following won't work. See https://ghc.haskell.org/trac/ghc/ticket/12853 -- when (ty4 /= ty4') $ failMsg "D" ty4 ty4' -- test #3: type quotations and reified types should agree wrt to -- promoted lists. ty5 <- [t| E '[True, False] |] ty6 <- [t| E [False, True] |] ClassI _ insts <- reify ''E let [ty5', ty6'] = map (withoutSig . getType) insts when (ty5 /= ty5') $ failMsg "C" ty5 ty5' when (ty6 /= ty6') $ failMsg "D" ty6 ty6' return []