module Data.Singletons.Single.Type where
import Language.Haskell.TH.Desugar
import Language.Haskell.TH.Syntax
import Data.Singletons.Names
import Data.Singletons.Single.Monad
import Data.Singletons.Promote.Type
import Data.Singletons.Util
import Control.Monad
data TopLevelFlag = TopLevel | NotTopLevel
singType :: TopLevelFlag
-> DType
-> DType
-> SgM ( DType
, Int
, [Name] )
singType top_level prom ty = do
let (cxt, tys) = unravel ty
args = init tys
num_args = length args
cxt' <- mapM singPred cxt
arg_names <- replicateM num_args (qNewName "t")
let args' = map (\n -> singFamily `DAppT` (DVarT n)) arg_names
res' = singFamily `DAppT` (foldl apply prom (map DVarT arg_names))
tau = ravel (args' ++ [res'])
ty' <- case top_level of
TopLevel -> do
prom_args <- mapM promoteType args
return $ DForallT (zipWith DKindedTV arg_names prom_args)
cxt' tau
NotTopLevel -> return $ DForallT (map DPlainTV arg_names)
cxt' tau
return (ty', num_args, arg_names)
singPred :: DPred -> SgM DPred
singPred = singPredRec []
singPredRec :: [DType] -> DPred -> SgM DPred
singPredRec ctx (DAppPr pr ty) = singPredRec (ty : ctx) pr
singPredRec _ctx (DSigPr _pr _ki) =
fail "Singling of constraints with explicit kinds not yet supported"
singPredRec _ctx (DVarPr _n) =
fail "Singling of contraint variables not yet supported"
singPredRec ctx (DConPr n)
| n == equalityName
= fail "Singling of type equality constraints not yet supported"
| otherwise = do
kis <- mapM promoteType ctx
let sName = singClassName n
return $ foldl DAppPr (DConPr sName) (map kindParam kis)