module DDC.Type.Compounds
(
takeNameOfBind
, typeOfBind
, replaceTypeOfBind
, binderOfBind
, makeBindFromBinder
, partitionBindsByType
, takeNameOfBound
, takeTypeOfBound
, boundMatchesBind
, namedBoundMatchesBind
, takeSubstBoundOfBind
, takeSubstBoundsOfBinds
, replaceTypeOfBound
, kFun
, kFuns
, takeKFun
, takeKFuns
, takeKFuns'
, takeResultKind
, tForall, tForall'
, tForalls, tForalls'
, takeTForalls, eraseTForalls
, tBot
, tSum
, tApp, ($:)
, tApps, takeTApps
, takeTyConApps
, takePrimTyConApps
, takeDataTyConApps
, takePrimeRegion
, tFun, tFunOfList
, tFunPE, tFunOfListPE
, tFunEC
, takeTFun, takeTFunEC
, takeTFunArgResult
, takeTFunWitArgResult
, takeTFunAllArgResult
, arityOfType
, tSusp
, tImpl
, tUnit
, tIx
, takeTExists
, sComp, sProp
, kData, kRegion, kEffect, kClosure, kWitness
, tRead, tDeepRead, tHeadRead
, tWrite, tDeepWrite
, tAlloc, tDeepAlloc
, tUse, tDeepUse
, tPure
, tEmpty
, tGlobal, tDeepGlobal
, tConst, tDeepConst
, tMutable, tDeepMutable
, tDistinct
, tLazy, tHeadLazy
, tManifest
, tConData0, tConData1)
where
import DDC.Type.Exp
import qualified DDC.Type.Sum as Sum
takeNameOfBind :: Bind n -> Maybe n
takeNameOfBind bb
= case bb of
BName n _ -> Just n
BAnon _ -> Nothing
BNone _ -> Nothing
typeOfBind :: Bind n -> Type n
typeOfBind bb
= case bb of
BName _ t -> t
BAnon t -> t
BNone t -> t
replaceTypeOfBind :: Type n -> Bind n -> Bind n
replaceTypeOfBind t bb
= case bb of
BName n _ -> BName n t
BAnon _ -> BAnon t
BNone _ -> BNone t
binderOfBind :: Bind n -> Binder n
binderOfBind bb
= case bb of
BName n _ -> RName n
BAnon _ -> RAnon
BNone _ -> RNone
makeBindFromBinder :: Binder n -> Type n -> Bind n
makeBindFromBinder bb t
= case bb of
RName n -> BName n t
RAnon -> BAnon t
RNone -> BNone t
partitionBindsByType :: Eq n => [Bind n] -> [([Binder n], Type n)]
partitionBindsByType [] = []
partitionBindsByType (b:bs)
= let t = typeOfBind b
bsSame = takeWhile (\b' -> typeOfBind b' == t) bs
rs = map binderOfBind (b:bsSame)
in (rs, t) : partitionBindsByType (drop (length bsSame) bs)
takeNameOfBound :: Bound n -> Maybe n
takeNameOfBound uu
= case uu of
UName n -> Just n
UPrim n _ -> Just n
UIx{} -> Nothing
takeTypeOfBound :: Bound n -> Maybe (Type n)
takeTypeOfBound uu
= case uu of
UName{} -> Nothing
UPrim _ t -> Just t
UIx{} -> Nothing
boundMatchesBind :: Eq n => Bound n -> Bind n -> Bool
boundMatchesBind u b
= case (u, b) of
(UName n1, BName n2 _) -> n1 == n2
(UIx 0, BAnon _) -> True
_ -> False
namedBoundMatchesBind :: Eq n => Bound n -> Bind n -> Bool
namedBoundMatchesBind u b
= case (u, b) of
(UName n1, BName n2 _) -> n1 == n2
_ -> False
takeSubstBoundOfBind :: Bind n -> Maybe (Bound n)
takeSubstBoundOfBind bb
= case bb of
BName n _ -> Just $ UName n
BAnon _ -> Just $ UIx 0
BNone _ -> Nothing
takeSubstBoundsOfBinds :: [Bind n] -> [Bound n]
takeSubstBoundsOfBinds bs
= go 1 bs
where go _level [] = []
go level (BName n _ : bs') = UName n : go level bs'
go level (BAnon _ : bs') = UIx (len level) : go (level + 1) bs'
go level (BNone _ : bs') = go level bs'
len = length [ () | BAnon _ <- bs]
replaceTypeOfBound :: Type n -> Bound n -> Bound n
replaceTypeOfBound t uu
= case uu of
UName{} -> uu
UPrim n _ -> UPrim n t
UIx{} -> uu
tIx :: Kind n -> Int -> Type n
tIx _ i = TVar (UIx i)
takeTExists :: Type n -> Maybe Int
takeTExists tt
= case tt of
TCon (TyConExists n _) -> Just n
_ -> Nothing
tBot :: Kind n -> Type n
tBot k = TSum $ Sum.empty k
tApp, ($:) :: Type n -> Type n -> Type n
tApp = TApp
($:) = TApp
tApps :: Type n -> [Type n] -> Type n
tApps t1 ts = foldl TApp t1 ts
takeTApps :: Type n -> [Type n]
takeTApps tt
= case tt of
TApp t1 t2 -> takeTApps t1 ++ [t2]
_ -> [tt]
takeTyConApps :: Type n -> Maybe (TyCon n, [Type n])
takeTyConApps tt
= case takeTApps tt of
TCon tc : args -> Just $ (tc, args)
_ -> Nothing
takePrimTyConApps :: Type n -> Maybe (n, [Type n])
takePrimTyConApps tt
= case takeTApps tt of
TCon tc : args
| TyConBound (UPrim n _) _ <- tc
-> Just (n, args)
_ -> Nothing
takeDataTyConApps :: Type n -> Maybe (TyCon n, [Type n])
takeDataTyConApps tt
= case takeTApps tt of
TCon tc : args
| TyConBound (UName{}) k <- tc
, TCon (TyConKind KiConData) <- takeResultKind k
-> Just (tc, args)
_ -> Nothing
takePrimeRegion :: Type n -> Maybe (Type n)
takePrimeRegion tt
= case takeTApps tt of
TCon _ : tR@(TVar _) : _
-> Just tR
_ -> Nothing
tForall :: Kind n -> (Type n -> Type n) -> Type n
tForall k f
= TForall (BAnon k) (f (TVar (UIx 0)))
tForall' :: Int -> Kind n -> (Type n -> Type n) -> Type n
tForall' ix k f
= TForall (BAnon k) (f (TVar (UIx ix)))
tForalls :: [Kind n] -> ([Type n] -> Type n) -> Type n
tForalls ks f
= let bs = [BAnon k | k <- ks]
us = map (\i -> TVar (UIx i)) [0 .. (length ks 1)]
in foldr TForall (f $ reverse us) bs
tForalls' :: Int -> [Kind n] -> ([Type n] -> Type n) -> Type n
tForalls' ix ks f
= let bs = [BAnon k | k <- ks]
us = map (\i -> TVar (UIx i)) [ix .. ix + (length ks 1)]
in foldr TForall (f $ reverse us) bs
takeTForalls :: Type n -> Maybe ([Bind n], Type n)
takeTForalls tt
= let go bs (TForall b t) = go (b:bs) t
go bs t = (reverse bs, t)
in case go [] tt of
([], _) -> Nothing
(bs, body) -> Just (bs, body)
eraseTForalls :: Ord n => Type n -> Type n
eraseTForalls tt
= case tt of
TVar{} -> tt
TCon{} -> tt
TForall _ t -> eraseTForalls t
TApp t1 t2 -> TApp (eraseTForalls t1) (eraseTForalls t2)
TSum ts -> TSum $ Sum.fromList (Sum.kindOfSum ts)
$ map eraseTForalls $ Sum.toList ts
tSum :: Ord n => Kind n -> [Type n] -> Type n
tSum k ts
= TSum (Sum.fromList k ts)
tUnit :: Type n
tUnit = TCon (TyConSpec TcConUnit)
kFun :: Kind n -> Kind n -> Kind n
kFun k1 k2 = ((TCon $ TyConKind KiConFun)`TApp` k1) `TApp` k2
infixr `kFun`
kFuns :: [Kind n] -> Kind n -> Kind n
kFuns [] k1 = k1
kFuns (k:ks) k1 = k `kFun` kFuns ks k1
takeKFun :: Kind n -> Maybe (Kind n, Kind n)
takeKFun kk
= case kk of
TApp (TApp (TCon (TyConKind KiConFun)) k1) k2
-> Just (k1, k2)
_ -> Nothing
takeKFuns :: Kind n -> ([Kind n], Kind n)
takeKFuns kk
= case kk of
TApp (TApp (TCon (TyConKind KiConFun)) k1) k2
| (ks, k2') <- takeKFuns k2
-> (k1 : ks, k2')
_ -> ([], kk)
takeKFuns' :: Kind n -> [Kind n]
takeKFuns' kk
| (ks, k1) <- takeKFuns kk
= ks ++ [k1]
takeResultKind :: Kind n -> Kind n
takeResultKind kk
= case kk of
TApp (TApp (TCon (TyConKind KiConFun)) _) k2
-> takeResultKind k2
_ -> kk
tFun :: Type n -> Type n -> Type n
tFun t1 t2
= (TCon $ TyConSpec TcConFun) `tApps` [t1, t2]
infixr `tFun`
tFunEC :: Type n -> Effect n -> Closure n -> Type n -> Type n
tFunEC t1 eff clo t2
= (TCon $ TyConSpec TcConFunEC) `tApps` [t1, eff, clo, t2]
infixr `tFunEC`
tFunPE :: Type n -> Type n -> Type n
tFunPE t1 t2 = tFunEC t1 (tBot kEffect) (tBot kClosure) t2
infixr `tFunPE`
tFunOfList :: [Type n] -> Maybe (Type n)
tFunOfList ts
= case reverse ts of
[] -> Nothing
(t : tsArgs)
-> let tFuns' [] = t
tFuns' (t' : ts') = t' `tFun` tFuns' ts'
in Just $ tFuns' (reverse tsArgs)
tFunOfListPE :: [Type n] -> Maybe (Type n)
tFunOfListPE ts
= case reverse ts of
[] -> Nothing
(t : tsArgs)
-> let tFunPEs' [] = t
tFunPEs' (t' : ts') = t' `tFunPE` tFunPEs' ts'
in Just $ tFunPEs' (reverse tsArgs)
takeTFun :: Type n -> Maybe (Type n, Type n)
takeTFun tt
= case tt of
TApp (TApp (TCon (TyConSpec TcConFun)) t1) t2
-> Just (t1, t2)
TApp (TApp (TApp (TApp (TCon (TyConSpec TcConFunEC)) t1) _eff) _clo) t2
-> Just (t1, t2)
_ -> Nothing
takeTFunEC :: Type n -> Maybe (Type n, Effect n, Closure n, Type n)
takeTFunEC tt
= case tt of
TApp (TApp (TApp (TApp (TCon (TyConSpec TcConFunEC)) t1) eff) clo) t2
-> Just (t1, eff, clo, t2)
_ -> Nothing
takeTFunArgResult :: Type n -> ([Type n], Type n)
takeTFunArgResult tt
= case tt of
TApp (TApp (TCon (TyConSpec TcConFun)) t1) t2
-> let (tsMore, tResult) = takeTFunArgResult t2
in (t1 : tsMore, tResult)
TApp (TApp (TApp (TApp (TCon (TyConSpec TcConFunEC)) t1) _eff) _clo) t2
-> let (tsMore, tResult) = takeTFunArgResult t2
in (t1 : tsMore, tResult)
_ -> ([], tt)
takeTFunWitArgResult :: Type n -> ([Type n], [Type n], Type n)
takeTFunWitArgResult tt
= case tt of
TApp (TApp (TCon (TyConWitness TwConImpl)) t1) t2
-> let (twsMore, tvsMore, tResult) = takeTFunWitArgResult t2
in (t1 : twsMore, tvsMore, tResult)
_ -> let (tvsMore, tResult) = takeTFunArgResult tt
in ([], tvsMore, tResult)
takeTFunAllArgResult :: Type n -> ([Type n], Type n)
takeTFunAllArgResult tt
= case tt of
TVar{} -> ([], tt)
TCon{} -> ([], tt)
TForall b t
-> let (tsMore, tResult) = takeTFunAllArgResult t
in (typeOfBind b : tsMore, tResult)
TApp (TApp (TCon (TyConSpec TcConFun)) t1) t2
-> let (tsMore, tResult) = takeTFunAllArgResult t2
in (t1 : tsMore, tResult)
TApp (TApp (TApp (TApp (TCon (TyConSpec TcConFunEC)) t1) _eff) _clo) t2
-> let (tsMore, tResult) = takeTFunAllArgResult t2
in (t1 : tsMore, tResult)
TApp (TApp (TCon (TyConWitness TwConImpl)) t1) t2
-> let (tsMore, tResult) = takeTFunAllArgResult t2
in (t1 : tsMore, tResult)
_ -> ([], tt)
arityOfType :: Type n -> Int
arityOfType tt
= case tt of
TForall _ t -> 1 + arityOfType t
t -> length $ fst $ takeTFunArgResult t
tImpl :: Type n -> Type n -> Type n
tImpl t1 t2
= ((TCon $ TyConWitness TwConImpl) `tApp` t1) `tApp` t2
infixr `tImpl`
tSusp :: Effect n -> Type n -> Type n
tSusp tE tA
= (TCon $ TyConSpec TcConSusp) `tApp` tE `tApp` tA
sComp = TCon $ TyConSort SoConComp
sProp = TCon $ TyConSort SoConProp
kData = TCon $ TyConKind KiConData
kRegion = TCon $ TyConKind KiConRegion
kEffect = TCon $ TyConKind KiConEffect
kClosure = TCon $ TyConKind KiConClosure
kWitness = TCon $ TyConKind KiConWitness
tRead = tcCon1 TcConRead
tHeadRead = tcCon1 TcConHeadRead
tDeepRead = tcCon1 TcConDeepRead
tWrite = tcCon1 TcConWrite
tDeepWrite = tcCon1 TcConDeepWrite
tAlloc = tcCon1 TcConAlloc
tDeepAlloc = tcCon1 TcConDeepAlloc
tUse = tcCon1 TcConUse
tDeepUse = tcCon1 TcConDeepUse
tPure = twCon1 TwConPure
tEmpty = twCon1 TwConEmpty
tGlobal = twCon1 TwConGlobal
tDeepGlobal = twCon1 TwConDeepGlobal
tConst = twCon1 TwConConst
tDeepConst = twCon1 TwConDeepConst
tMutable = twCon1 TwConMutable
tDeepMutable = twCon1 TwConDeepMutable
tDistinct n = twCon2 (TwConDistinct n)
tLazy = twCon1 TwConLazy
tHeadLazy = twCon1 TwConHeadLazy
tManifest = twCon1 TwConManifest
tcCon1 tc t = (TCon $ TyConSpec tc) `tApp` t
twCon1 tc t = (TCon $ TyConWitness tc) `tApp` t
twCon2 tc ts = tApps (TCon $ TyConWitness tc) ts
tConData0 :: n -> Kind n -> Type n
tConData0 n k = TCon (TyConBound (UName n) k)
tConData1 :: n -> Kind n -> Type n -> Type n
tConData1 n k t1 = TApp (TCon (TyConBound (UName n) k)) t1