{-# LANGUAGE ExplicitNamespaces, CPP #-}
module Data.Singletons.TH (
singletons, singletonsOnly, genSingletons,
promote, promoteOnly, genDefunSymbols, genPromotions,
promoteEqInstances, promoteEqInstance,
singEqInstances, singEqInstance,
singEqInstancesOnly, singEqInstanceOnly,
singDecideInstances, singDecideInstance,
promoteOrdInstances, promoteOrdInstance,
singOrdInstances, singOrdInstance,
promoteBoundedInstances, promoteBoundedInstance,
singBoundedInstances, singBoundedInstance,
promoteEnumInstances, promoteEnumInstance,
singEnumInstances, singEnumInstance,
promoteShowInstances, promoteShowInstance,
singShowInstances, singShowInstance,
cases, sCases,
Sing(SFalse, STrue, STuple0, STuple2, STuple3, STuple4, STuple5, STuple6, STuple7,
SLT, SEQ, SGT),
module Data.Singletons,
PEq(..), If, sIf, type (&&), (%&&), SEq(..),
POrd(..), SOrd(..), ThenCmp, sThenCmp, Foldl, sFoldl,
SDecide(..), (:~:)(..), Void, Refuted, Decision(..),
PBounded(..), SBounded(..),
PEnum(FromEnum, ToEnum), SEnum(sFromEnum, sToEnum),
PShow(..), SShow(..),
ShowString, sShowString, ShowParen, sShowParen, ShowSpace, sShowSpace,
ShowChar, sShowChar, ShowCommaSpace, sShowCommaSpace,
(:.), (%.),
SomeSing(..),
Error, sError, ErrorSym0, ErrorSym1,
Undefined, sUndefined, UndefinedSym0,
TrueSym0, FalseSym0,
type (==@#@$), type (==@#@$$), type (==@#@$$$),
type (>@#@$), type (>@#@$$), type (>@#@$$$),
LTSym0, EQSym0, GTSym0,
Tuple0Sym0,
Tuple2Sym0, Tuple2Sym1, Tuple2Sym2,
Tuple3Sym0, Tuple3Sym1, Tuple3Sym2, Tuple3Sym3,
Tuple4Sym0, Tuple4Sym1, Tuple4Sym2, Tuple4Sym3, Tuple4Sym4,
Tuple5Sym0, Tuple5Sym1, Tuple5Sym2, Tuple5Sym3, Tuple5Sym4, Tuple5Sym5,
Tuple6Sym0, Tuple6Sym1, Tuple6Sym2, Tuple6Sym3, Tuple6Sym4, Tuple6Sym5, Tuple6Sym6,
Tuple7Sym0, Tuple7Sym1, Tuple7Sym2, Tuple7Sym3, Tuple7Sym4, Tuple7Sym5, Tuple7Sym6, Tuple7Sym7,
CompareSym0, CompareSym1, CompareSym2,
ThenCmpSym0, ThenCmpSym1, ThenCmpSym2,
FoldlSym0, FoldlSym1, FoldlSym2, FoldlSym3,
MinBoundSym0, MaxBoundSym0,
ShowsPrecSym0, ShowsPrecSym1, ShowsPrecSym2, ShowsPrecSym3,
ShowStringSym0, ShowStringSym1, ShowStringSym2,
ShowParenSym0, ShowParenSym1, ShowParenSym2,
ShowSpaceSym0, ShowSpaceSym1,
ShowCharSym0, ShowCharSym1, ShowCharSym2,
ShowCommaSpaceSym0, ShowCommaSpaceSym1,
type (.@#@$), type (.@#@$$), type (.@#@$$$), type (.@#@$$$$),
(:@#@$), (:@#@$$), (:@#@$$$),
SuppressUnusedWarnings(..)
) where
import Data.Singletons
import Data.Singletons.Single
import Data.Singletons.Promote
import Data.Singletons.Prelude.Base
import Data.Singletons.Prelude.Instances
import Data.Singletons.Prelude.Bool
import Data.Singletons.Prelude.Enum
import Data.Singletons.Prelude.Eq
import Data.Singletons.Prelude.Ord
import Data.Singletons.Prelude.Show
import Data.Singletons.Decide
import Data.Singletons.TypeLits
import Data.Singletons.SuppressUnusedWarnings
import Data.Singletons.Names
import Language.Haskell.TH.Desugar
import Language.Haskell.TH
import Data.Singletons.Util
import Control.Arrow ( first )
cases :: DsMonad q
=> Name
-> q Exp
-> q Exp
-> q Exp
cases tyName expq bodyq = do
dinfo <- dsReify tyName
case dinfo of
Just (DTyConI (DDataD _ _ _ _ ctors _) _) ->
expToTH <$> buildCases (map extractNameArgs ctors) expq bodyq
Just _ ->
fail $ "Using <<cases>> with something other than a type constructor: "
++ (show tyName)
_ -> fail $ "Cannot find " ++ show tyName
sCases :: DsMonad q
=> Name
-> q Exp
-> q Exp
-> q Exp
sCases tyName expq bodyq = do
dinfo <- dsReify tyName
case dinfo of
Just (DTyConI (DDataD _ _ _ _ ctors _) _) ->
let ctor_stuff = map (first singDataConName . extractNameArgs) ctors in
expToTH <$> buildCases ctor_stuff expq bodyq
Just _ ->
fail $ "Using <<cases>> with something other than a type constructor: "
++ (show tyName)
_ -> fail $ "Cannot find " ++ show tyName
buildCases :: DsMonad m
=> [(Name, Int)]
-> m Exp
-> m Exp
-> m DExp
buildCases ctor_infos expq bodyq =
DCaseE <$> (dsExp =<< expq) <*>
mapM (\con -> DMatch (conToPat con) <$> (dsExp =<< bodyq)) ctor_infos
where
conToPat :: (Name, Int) -> DPat
conToPat (name, num_fields) =
DConPa name (replicate num_fields DWildPa)