module Data.Singletons.TH (
singletons, singletonsOnly, genSingletons,
promote, promoteOnly,
promoteEqInstances, promoteEqInstance,
singEqInstances, singEqInstance,
singEqInstancesOnly, singEqInstanceOnly,
singDecideInstances, singDecideInstance,
cases,
Sing(SFalse, STrue), SingI(..), SingKind(..), KindOf, Demote,
type (==), (:==), If, sIf, (:&&), SEq(..),
Any,
SDecide(..), (:~:)(..), Void, Refuted, Decision(..),
KProxy(..), SomeSing(..)
) where
import Data.Singletons
import Data.Singletons.Singletons
import Data.Singletons.Promote
import Data.Singletons.Instances
import Data.Singletons.Bool
import Data.Singletons.Eq
import Data.Singletons.Types
import Data.Singletons.Void
import Data.Singletons.Decide
import GHC.Exts
import Language.Haskell.TH
import Language.Haskell.TH.Syntax ( Quasi(..) )
import Language.Haskell.TH.Desugar
import Data.Singletons.Util
import Control.Applicative
cases :: Quasi q
=> Name
-> q Exp
-> q Exp
-> q Exp
cases tyName expq bodyq = do
info <- reifyWithWarning tyName
case info of
TyConI (DataD _ _ _ ctors _) -> buildCases ctors
TyConI (NewtypeD _ _ _ ctor _) -> buildCases [ctor]
_ -> fail $ "Using <<cases>> with something other than a type constructor: "
++ (show tyName)
where buildCases ctors =
CaseE <$> expq <*>
mapM (\con -> Match (conToPat con) <$>
(NormalB <$> bodyq) <*> pure []) ctors
conToPat :: Con -> Pat
conToPat = ctor1Case
(\name tys -> ConP name (map (const WildP) tys))