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
import qualified Data.Set as Set
import Data.Set (Set)
singType :: Set Name
-> DType
-> DType
-> SgM ( DType
, Int
, [Name]
, DCxt
, [DKind]
, DKind )
singType bound_kvs prom ty = do
let (_, cxt, args, res) = unravel ty
num_args = length args
cxt' <- mapM singPred cxt
arg_names <- replicateM num_args (qNewName "t")
prom_args <- mapM promoteType args
prom_res <- promoteType res
let args' = map (\n -> singFamily `DAppT` (DVarT n)) arg_names
res' = singFamily `DAppT` (foldl apply prom (map DVarT arg_names) `DSigT` prom_res)
tau = ravel args' res'
kv_names_to_bind = foldMap fvDType (prom_args ++ map predToType cxt' ++ [prom_res])
Set.\\ bound_kvs
kvs_to_bind = Set.toList kv_names_to_bind
let ty' = DForallT (map DPlainTV kvs_to_bind ++ zipWith DKindedTV arg_names prom_args)
cxt' tau
return (ty', num_args, arg_names, cxt, prom_args, prom_res)
singPred :: DPred -> SgM DPred
singPred = singPredRec []
singPredRec :: [DType] -> DPred -> SgM DPred
singPredRec _cxt (DForallPr {}) =
fail "Singling of quantified constraints not yet supported"
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 $ foldPred (DConPr sName) kis
singPredRec _ctx DWildCardPr = return DWildCardPr