{-# 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,
SDecide(..), (:~:)(..), Void, Refuted, Decision(..),
PBounded(..), SBounded(..),
PEnum(FromEnum, ToEnum), SEnum(sFromEnum, sToEnum),
PShow(..), SShow(..),
ShowString, sShowString, ShowParen, sShowParen, ShowSpace, sShowSpace,
ShowChar, sShowChar, ShowCommaSpace, sShowCommaSpace,
PFunctor(..), SFunctor(..),
PFoldable(..), SFoldable(..), PMonoid(..), SMonoid(..),
PTraversable(..), STraversable(..), PApplicative(..), SApplicative(..),
(:.), (%.),
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,
FmapSym0, FmapSym1, FmapSym2,
type (<$@#@$), type (<$@#@$$), type (<$@#@$$$),
FoldMapSym0, FoldMapSym1, FoldMapSym2,
MemptySym0,
MappendSym0, MappendSym1, MappendSym2,
FoldrSym0, FoldrSym1, FoldrSym2, FoldrSym3,
TraverseSym0, TraverseSym1, TraverseSym2,
PureSym0, PureSym1,
type (<*>@#@$), type (<*>@#@$$), type (<*>@#@$$$),
LiftA2Sym0, LiftA2Sym1, LiftA2Sym2, LiftA2Sym3,
type (.@#@$), type (.@#@$$), type (.@#@$$$), type (.@#@$$$$),
(:@#@$), (:@#@$$), (:@#@$$$),
SuppressUnusedWarnings(..)
) where
import Data.Singletons
import Data.Singletons.Single
import Data.Singletons.Promote
import Data.Singletons.Prelude.Applicative
import Data.Singletons.Prelude.Base
hiding (Foldr, FoldrSym0, FoldrSym1, FoldrSym2, FoldrSym3, sFoldr)
import Data.Singletons.Prelude.Instances
hiding (Foldl, FoldlSym0, FoldlSym1, FoldlSym2, FoldlSym3, sFoldl)
import Data.Singletons.Prelude.Bool
import Data.Singletons.Prelude.Enum
import Data.Singletons.Prelude.Eq
import Data.Singletons.Prelude.Foldable
import Data.Singletons.Prelude.Functor hiding (Void)
import Data.Singletons.Prelude.Monoid
import Data.Singletons.Prelude.Ord
import Data.Singletons.Prelude.Show
import Data.Singletons.Prelude.Traversable
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)