-- Apply the vectorisation transformation to types. This is the \mathcal{L}_t scheme in HtM. module Vectorise.Type.Type ( vectTyCon , vectAndLiftType , vectType ) where import GhcPrelude import Vectorise.Utils import Vectorise.Monad import Vectorise.Builtins import TcType import Type import TyCoRep import TyCon import Control.Monad import Data.Maybe import Outputable -- |Vectorise a type constructor. Unless there is a vectorised version (stripped of embedded -- parallel arrays), the vectorised version is the same as the original. -- vectTyCon :: TyCon -> VM TyCon vectTyCon tc = maybe tc id <$> lookupTyCon tc -- |Produce the vectorised and lifted versions of a type. -- -- NB: Here we are limited to properly handle predicates at the toplevel only. Anything embedded -- in what is called the 'body_ty' below will end up as an argument to the type family 'PData'. -- vectAndLiftType :: Type -> VM (Type, Type) vectAndLiftType ty | Just ty' <- coreView ty = vectAndLiftType ty' vectAndLiftType ty = do { padicts <- liftM catMaybes $ mapM paDictArgType tyvars ; vmono_ty <- vectType mono_ty ; lmono_ty <- mkPDataType vmono_ty ; return (abstractType tyvars (padicts ++ theta) vmono_ty, abstractType tyvars (padicts ++ theta) lmono_ty) } where (tyvars, phiTy) = splitForAllTys ty (theta, mono_ty) = tcSplitPhiTy phiTy -- |Vectorise a type. -- -- For each quantified var we need to add a PA dictionary out the front of the type. -- So forall a. C a => a -> a -- turns into forall a. PA a => Cv a => a :-> a -- vectType :: Type -> VM Type vectType ty | Just ty' <- coreView ty = vectType ty' vectType (TyVarTy tv) = return $ TyVarTy tv vectType (LitTy l) = return $ LitTy l vectType (AppTy ty1 ty2) = AppTy <$> vectType ty1 <*> vectType ty2 vectType (TyConApp tc tys) = TyConApp <$> vectTyCon tc <*> mapM vectType tys vectType (FunTy ty1 ty2) | isPredTy ty1 = mkFunTy <$> vectType ty1 <*> vectType ty2 -- don't build a closure for dictionary abstraction | otherwise = TyConApp <$> builtin closureTyCon <*> mapM vectType [ty1, ty2] vectType ty@(ForAllTy {}) = do { -- strip off consecutive foralls ; let (tyvars, tyBody) = splitForAllTys ty -- vectorise the body ; vtyBody <- vectType tyBody -- make a PA dictionary for each of the type variables ; dictsPA <- liftM catMaybes $ mapM paDictArgType tyvars -- add the PA dictionaries after the foralls ; return $ abstractType tyvars dictsPA vtyBody } vectType ty@(CastTy {}) = pprSorry "Vectorise.Type.Type.vectType: CastTy" (ppr ty) vectType ty@(CoercionTy {}) = pprSorry "Vectorise.Type.Type.vectType: CoercionTy" (ppr ty) -- |Add quantified vars and dictionary parameters to the front of a type. -- abstractType :: [TyVar] -> [Type] -> Type -> Type abstractType tyvars dicts = mkInvForAllTys tyvars . mkFunTys dicts