Simon Peyton Jones pushed to branch wip/substitution-via-mapper at Glasgow Haskell Compiler / GHC
Commits:
-
9890c886
by Simon Peyton Jones at 2026-08-04T11:52:22+01:00
5 changed files:
- compiler/GHC/Core/TyCo/Make.hs
- compiler/GHC/Core/TyCo/Subst.hs
- compiler/GHC/Core/Type.hs
- + compiler/GHC/Utils/StrictIdentity.hs
- compiler/ghc.cabal.in
Changes:
| ... | ... | @@ -48,14 +48,12 @@ module GHC.Core.TyCo.Make ( |
| 48 | 48 | -- Coercions
|
| 49 | 49 | , mkReflCo, mkNomReflCo, mkRepReflCo
|
| 50 | 50 | , mkCoVarCo, mkCoVarCos, mkHoleCo
|
| 51 | - , mkKindCo, mkSelCo
|
|
| 51 | + , mkKindCo
|
|
| 52 | 52 | , mkGReflCo, mkGReflRightCo, mkGReflLeftCo
|
| 53 | 53 | , mkGReflMCo, mkGReflRightMCo, mkGReflLeftMCo
|
| 54 | 54 | , mkSubCo, mkSymCo, mkSymMCo
|
| 55 | 55 | , mkFunCo2, mkForAllCo, mkUnivCo
|
| 56 | 56 | , mkAxiomCo, mkUnbranchedAxInstCo
|
| 57 | - , mkAppCo, mkTyConAppCo
|
|
| 58 | - , mkInstCo, mkLRCo
|
|
| 59 | 57 | , mkFunCo, mkNakedFunCo
|
| 60 | 58 | , mkNakedForAllCo, mkForAllVisCos, mkHomoForAllCo, mkHomoForAllCos
|
| 61 | 59 | , mkAxInstCo
|
| ... | ... | @@ -83,7 +81,7 @@ module GHC.Core.TyCo.Make ( |
| 83 | 81 | import GHC.Prelude
|
| 84 | 82 | |
| 85 | 83 | import {-# SOURCE #-} GHC.Core.Coercion
|
| 86 | - ( mkLRCo, mkInstCo, mkAppCo, mkAppCos, mkTyConAppCo, mkSelCo
|
|
| 84 | + ( mkLRCo, mkInstCo, mkAppCo, mkAppCos, mkSelCo
|
|
| 87 | 85 | , decomposePiCos
|
| 88 | 86 | , isKindCo
|
| 89 | 87 | , coercionKind -- Used in toPhantomCo
|
| ... | ... | @@ -222,60 +220,60 @@ mapTyCoX (TyCoMapper { tcm_tyvar = tyvar |
| 222 | 220 | = (go_ty, go_tys, go_co, go_cos)
|
| 223 | 221 | where
|
| 224 | 222 | -- See Note [Use explicit recursion in mapTyCo]
|
| 225 | - go_tys !_ [] = return []
|
|
| 226 | - go_tys !env (ty:tys) = (:) <$> go_ty env ty <*> go_tys env tys
|
|
| 223 | + go_tys _ [] = return []
|
|
| 224 | + go_tys env (ty:tys) = (:) <$> go_ty env ty <*> go_tys env tys
|
|
| 227 | 225 | |
| 228 | - go_ty !env (TyVarTy tv) = tyvar env tv
|
|
| 229 | - go_ty !env (AppTy t1 t2) = mkAppTy <$> go_ty env t1 <*> go_ty env t2
|
|
| 230 | - go_ty !_ ty@(LitTy {}) = return ty
|
|
| 231 | - go_ty !env (CastTy ty co) = mkCastTy <$> go_ty env ty <*> go_co env co
|
|
| 232 | - go_ty !env (CoercionTy co) = CoercionTy <$> go_co env co
|
|
| 226 | + go_ty env (TyVarTy tv) = tyvar env tv
|
|
| 227 | + go_ty env (AppTy t1 t2) = mkAppTy <$> go_ty env t1 <*> go_ty env t2
|
|
| 228 | + go_ty _ ty@(LitTy {}) = return ty
|
|
| 229 | + go_ty env (CastTy ty co) = mkCastTy <$> go_ty env ty <*> go_co env co
|
|
| 230 | + go_ty env (CoercionTy co) = CoercionTy <$> go_co env co
|
|
| 233 | 231 | |
| 234 | - go_ty !env ty@(FunTy _ w arg res)
|
|
| 232 | + go_ty env ty@(FunTy _ w arg res)
|
|
| 235 | 233 | = do { w' <- go_ty env w; arg' <- go_ty env arg; res' <- go_ty env res
|
| 236 | 234 | ; return (ty { ft_mult = w', ft_arg = arg', ft_res = res' }) }
|
| 237 | 235 | |
| 238 | - go_ty !env ty@(TyConApp tc tys)
|
|
| 236 | + go_ty env ty@(TyConApp tc tys)
|
|
| 239 | 237 | = do { tys' <- go_tys env tys; tcapp_ty env ty tc tys' }
|
| 240 | 238 | |
| 241 | - go_ty !env (ForAllTy (Bndr tv vis) inner)
|
|
| 239 | + go_ty env (ForAllTy (Bndr tv vis) inner)
|
|
| 242 | 240 | = do { tycobinder env tv vis $ \env' tv' -> do
|
| 243 | 241 | ; inner' <- go_ty env' inner
|
| 244 | 242 | ; return $ ForAllTy (Bndr tv' vis) inner' }
|
| 245 | 243 | |
| 246 | 244 | -- See Note [Use explicit recursion in mapTyCo]
|
| 247 | - go_cos !_ [] = return []
|
|
| 248 | - go_cos !env (co:cos) = (:) <$> go_co env co <*> go_cos env cos
|
|
| 245 | + go_cos _ [] = return []
|
|
| 246 | + go_cos env (co:cos) = (:) <$> go_co env co <*> go_cos env cos
|
|
| 249 | 247 | |
| 250 | - go_mco !_ MRefl = return MRefl
|
|
| 251 | - go_mco !env (MCo co) = MCo <$> (go_co env co)
|
|
| 248 | + go_mco _ MRefl = return MRefl
|
|
| 249 | + go_mco env (MCo co) = MCo <$> (go_co env co)
|
|
| 252 | 250 | |
| 253 | 251 | go_co :: env -> Coercion -> m Coercion
|
| 254 | - go_co !env (Refl ty) = Refl <$> go_ty env ty
|
|
| 255 | - go_co !env (GRefl r ty mco) = mkGReflCo r <$> go_ty env ty <*> go_mco env mco
|
|
| 256 | - go_co !env (AppCo c1 c2) = mkAppCo <$> go_co env c1 <*> go_co env c2
|
|
| 257 | - go_co !env (FunCo r afl afr cw c1 c2) = mkFunCo2 r afl afr <$> go_co env cw
|
|
| 252 | + go_co env (Refl ty) = Refl <$> go_ty env ty
|
|
| 253 | + go_co env (GRefl r ty mco) = mkGReflCo r <$> go_ty env ty <*> go_mco env mco
|
|
| 254 | + go_co env (AppCo c1 c2) = mkAppCo <$> go_co env c1 <*> go_co env c2
|
|
| 255 | + go_co env (FunCo r afl afr cw c1 c2) = mkFunCo2 r afl afr <$> go_co env cw
|
|
| 258 | 256 | <*> go_co env c1 <*> go_co env c2
|
| 259 | - go_co !env (CoVarCo cv) = covar env cv
|
|
| 260 | - go_co !env (HoleCo hole) = cohole env hole
|
|
| 261 | - go_co !env (UnivCo { uco_prov = p, uco_role = r
|
|
| 262 | - , uco_lty = t1, uco_rty = t2, uco_deps = deps })
|
|
| 263 | - = mkUnivCo <$> pure p
|
|
| 264 | - <*> go_cos env deps
|
|
| 265 | - <*> pure r
|
|
| 266 | - <*> go_ty env t1 <*> go_ty env t2
|
|
| 267 | - go_co !env (SymCo co) = mkSymCo <$> go_co env co
|
|
| 268 | - go_co !env (TransCo c1 c2) = mkTransCo <$> go_co env c1 <*> go_co env c2
|
|
| 269 | - go_co !env (AxiomCo r cos) = mkAxiomCo r <$> go_cos env cos
|
|
| 270 | - go_co !env (SelCo i co) = SelCo i <$> go_co env co
|
|
| 271 | - go_co !env (LRCo lr co) = mkLRCo lr <$> go_co env co
|
|
| 272 | - go_co !env (InstCo co arg) = mkInstCo <$> go_co env co <*> go_co env arg
|
|
| 273 | - go_co !env (KindCo co) = mkKindCo <$> go_co env co
|
|
| 274 | - go_co !env (SubCo co) = mkSubCo <$> go_co env co
|
|
| 275 | - go_co !env co@(TyConAppCo r tc cos) = do { cos' <- go_cos env cos
|
|
| 257 | + go_co env (CoVarCo cv) = covar env cv
|
|
| 258 | + go_co env (HoleCo hole) = cohole env hole
|
|
| 259 | + go_co env (UnivCo { uco_prov = p, uco_role = r
|
|
| 260 | + , uco_lty = t1, uco_rty = t2, uco_deps = deps })
|
|
| 261 | + = mkUnivCo <$> pure p
|
|
| 262 | + <*> go_cos env deps
|
|
| 263 | + <*> pure r
|
|
| 264 | + <*> go_ty env t1 <*> go_ty env t2
|
|
| 265 | + go_co env (SymCo co) = mkSymCo <$> go_co env co
|
|
| 266 | + go_co env (TransCo c1 c2) = mkTransCo <$> go_co env c1 <*> go_co env c2
|
|
| 267 | + go_co env (AxiomCo r cos) = mkAxiomCo r <$> go_cos env cos
|
|
| 268 | + go_co env (SelCo i co) = mkSelCo i <$> go_co env co
|
|
| 269 | + go_co env (LRCo lr co) = mkLRCo lr <$> go_co env co
|
|
| 270 | + go_co env (InstCo co arg) = mkInstCo <$> go_co env co <*> go_co env arg
|
|
| 271 | + go_co env (KindCo co) = mkKindCo <$> go_co env co
|
|
| 272 | + go_co env (SubCo co) = mkSubCo <$> go_co env co
|
|
| 273 | + go_co env co@(TyConAppCo r tc cos) = do { cos' <- go_cos env cos
|
|
| 276 | 274 | ; tcapp_co env co r tc cos' }
|
| 277 | - go_co !env (ForAllCo { fco_tcv = tv, fco_visL = visL, fco_visR = visR
|
|
| 278 | - , fco_kind = kind_co, fco_body = co })
|
|
| 275 | + go_co env (ForAllCo { fco_tcv = tv, fco_visL = visL, fco_visR = visR
|
|
| 276 | + , fco_kind = kind_co, fco_body = co })
|
|
| 279 | 277 | = do { kind_co' <- go_mco env kind_co
|
| 280 | 278 | ; tycobinder env tv visL $ \env' tv' -> do
|
| 281 | 279 | ; co' <- go_co env' co
|
| ... | ... | @@ -53,7 +53,7 @@ module GHC.Core.TyCo.Subst |
| 53 | 53 | import GHC.Prelude
|
| 54 | 54 | |
| 55 | 55 | |
| 56 | -import {-# SOURCE #-} GHC.Core.Coercion ( mkCoercionType, coVarTypesRole )
|
|
| 56 | +import {-# SOURCE #-} GHC.Core.Coercion ( mkCoercionType, coVarTypesRole, mkTyConAppCo )
|
|
| 57 | 57 | import {-# SOURCE #-} GHC.Core.TyCo.Ppr ( pprTyVar )
|
| 58 | 58 | import {-# SOURCE #-} GHC.Core.Ppr ( ) -- instance Outputable CoreExpr
|
| 59 | 59 | import {-# SOURCE #-} GHC.Core ( CoreExpr )
|
| ... | ... | @@ -76,8 +76,8 @@ import GHC.Utils.Constants (debugIsOn) |
| 76 | 76 | import GHC.Utils.Misc
|
| 77 | 77 | import GHC.Utils.Outputable
|
| 78 | 78 | import GHC.Utils.Panic
|
| 79 | +import GHC.Utils.StrictIdentity
|
|
| 79 | 80 | |
| 80 | -import Data.Functor.Identity ( Identity (..) )
|
|
| 81 | 81 | import Data.List (mapAccumL)
|
| 82 | 82 | |
| 83 | 83 | {-
|
| ... | ... | @@ -769,8 +769,9 @@ substTheta = substTys |
| 769 | 769 | substThetaUnchecked :: Subst -> ThetaType -> ThetaType
|
| 770 | 770 | substThetaUnchecked = substTysUnchecked
|
| 771 | 771 | |
| 772 | - |
|
| 773 | -substTyCoMapper :: TyCoMapper Subst Identity
|
|
| 772 | +substTyCoMapper :: TyCoMapper Subst StrictIdentity
|
|
| 773 | +-- Use StrictIdentity, so that the entire mapping
|
|
| 774 | +-- operation is strict, building no thunks
|
|
| 774 | 775 | substTyCoMapper
|
| 775 | 776 | = TyCoMapper { tcm_tyvar = subst_tv
|
| 776 | 777 | , tcm_covar = subst_cv
|
| ... | ... | @@ -787,16 +788,16 @@ substTyCoMapper |
| 787 | 788 | tcv_bndr subst tcv _vis k
|
| 788 | 789 | = k subst' tcv'
|
| 789 | 790 | where
|
| 790 | - (subst', tcv') = substVarBndrUnchecked subst tcv
|
|
| 791 | + !(subst', tcv') = substVarBndrUnchecked subst tcv
|
|
| 791 | 792 | -- Sadly unchecked because subst_ty is used from substTyUnchecked
|
| 792 | 793 | |
| 793 | 794 | -- Avoid allocation in this very
|
| 794 | 795 | -- common case (E.g. Int, LiftedRep etc)
|
| 795 | - tcapp_ty :: Subst -> Type -> TyCon -> [Type] -> Identity Type
|
|
| 796 | + tcapp_ty :: Subst -> Type -> TyCon -> [Type] -> StrictIdentity Type
|
|
| 796 | 797 | tcapp_ty _ ty tc tys'
|
| 797 | 798 | | null tys' = return ty
|
| 798 | 799 | | otherwise = return (mkTyConApp tc tys')
|
| 799 | - tcapp_co :: Subst -> Coercion -> Role -> TyCon -> [Coercion] -> Identity Coercion
|
|
| 800 | + tcapp_co :: Subst -> Coercion -> Role -> TyCon -> [Coercion] -> StrictIdentity Coercion
|
|
| 800 | 801 | tcapp_co _ co r tc cos'
|
| 801 | 802 | | null cos' = return co
|
| 802 | 803 | | otherwise = return (mkTyConAppCo r tc cos')
|
| ... | ... | @@ -807,43 +808,8 @@ subst_co :: Subst -> Coercion -> Coercion |
| 807 | 808 | = case mapTyCoX substTyCoMapper of
|
| 808 | 809 | (ms_ty, _, ms_co, _) -> (run ms_ty, run ms_co)
|
| 809 | 810 | where
|
| 810 | - run :: forall a. (Subst -> a -> Identity a) -> Subst -> a -> a
|
|
| 811 | - run ms subst x = runIdentity (ms subst x)
|
|
| 812 | - |
|
| 813 | -{-
|
|
| 814 | -subst_ty :: Subst -> Type -> Type
|
|
| 815 | --- subst_ty is the main workhorse for type substitution
|
|
| 816 | ---
|
|
| 817 | --- Note that the in_scope set is poked only if we hit a forall
|
|
| 818 | --- so it may often never be fully computed
|
|
| 819 | -subst_ty subst ty
|
|
| 820 | - = go ty
|
|
| 821 | - where
|
|
| 822 | - go (TyVarTy tv) = substTyVar subst tv
|
|
| 823 | - go (AppTy fun arg) = (mkAppTy $! (go fun)) $! (go arg)
|
|
| 824 | - -- The mkAppTy smart constructor is important
|
|
| 825 | - -- we might be replacing (a Int), represented with App
|
|
| 826 | - -- by [Int], represented with TyConApp
|
|
| 827 | - go ty@(TyConApp tc []) = tc `seq` ty -- avoid allocation in this common case
|
|
| 828 | - go (TyConApp tc tys) = (mkTyConApp $! tc) $! strictMap go tys
|
|
| 829 | - -- NB: mkTyConApp, not TyConApp.
|
|
| 830 | - -- mkTyConApp has optimizations.
|
|
| 831 | - -- See Note [Using synonyms to compress types]
|
|
| 832 | - -- in GHC.Core.Type
|
|
| 833 | - go ty@(FunTy { ft_mult = mult, ft_arg = arg, ft_res = res })
|
|
| 834 | - = let !mult' = go mult
|
|
| 835 | - !arg' = go arg
|
|
| 836 | - !res' = go res
|
|
| 837 | - in ty { ft_mult = mult', ft_arg = arg', ft_res = res' }
|
|
| 838 | - go (ForAllTy (Bndr tv vis) ty)
|
|
| 839 | - = (ForAllTy $! ((Bndr $! tv') vis)) $! (subst_ty subst' ty)
|
|
| 840 | - where
|
|
| 841 | - !(subst',tv') = substVarBndrUnchecked subst tv
|
|
| 842 | - -- Unchecked because subst_ty is used from substTyUnchecked
|
|
| 843 | - go (LitTy n) = LitTy $! n
|
|
| 844 | - go (CastTy ty co) = (mkCastTy $! (go ty)) $! (subst_co subst co)
|
|
| 845 | - go (CoercionTy co) = CoercionTy $! (subst_co subst co)
|
|
| 846 | --}
|
|
| 811 | + run :: forall a. (Subst -> a -> StrictIdentity a) -> Subst -> a -> a
|
|
| 812 | + run ms subst x = runStrictIdentity (ms subst x)
|
|
| 847 | 813 | |
| 848 | 814 | substTyVar :: Subst -> TyVar -> Type
|
| 849 | 815 | substTyVar (Subst _ _ tenv _) tv
|
| ... | ... | @@ -885,51 +851,6 @@ substCos subst cos |
| 885 | 851 | | isEmptyTCvSubst subst = cos
|
| 886 | 852 | | otherwise = checkValidSubst subst [] cos $ map (subst_co subst) cos
|
| 887 | 853 | |
| 888 | -{-
|
|
| 889 | -subst_co :: HasDebugCallStack => Subst -> Coercion -> Coercion
|
|
| 890 | -subst_co subst co
|
|
| 891 | - = go co
|
|
| 892 | - where
|
|
| 893 | - go_ty :: Type -> Type
|
|
| 894 | - go_ty = subst_ty subst
|
|
| 895 | - |
|
| 896 | - go_mco :: MCoercion -> MCoercion
|
|
| 897 | - go_mco MRefl = MRefl
|
|
| 898 | - go_mco (MCo co) = MCo (go co)
|
|
| 899 | - |
|
| 900 | - go :: Coercion -> Coercion
|
|
| 901 | - go (Refl ty) = mkNomReflCo $! (go_ty ty)
|
|
| 902 | - go (GRefl r ty mco) = (mkGReflCo r $! (go_ty ty)) $! (go_mco mco)
|
|
| 903 | - go (TyConAppCo r tc args)= mkTyConAppCo r tc $! go_cos args
|
|
| 904 | - go (AxiomCo con cos) = mkAxiomCo con $! go_cos cos
|
|
| 905 | - go (AppCo co arg) = (mkAppCo $! go co) $! go arg
|
|
| 906 | - go (ForAllCo { fco_tcv = tcv, fco_visL = visL, fco_visR = visR
|
|
| 907 | - , fco_kind = kind_co, fco_body = co })
|
|
| 908 | - = ((mkForAllCo $! tcv') visL visR
|
|
| 909 | - $! go_mco kind_co)
|
|
| 910 | - $! subst_co subst' co
|
|
| 911 | - where
|
|
| 912 | - !(subst', tcv') = substVarBndrUnchecked subst tcv
|
|
| 913 | - -- Unchecked because used from substTyUnchecked
|
|
| 914 | - go (FunCo r afl afr w co1 co2) = ((mkFunCo2 r afl afr $! go w) $! go co1) $! go co2
|
|
| 915 | - go (CoVarCo cv) = substCoVar subst cv
|
|
| 916 | - go (HoleCo h) = substCoHole subst h
|
|
| 917 | - go (UnivCo { uco_prov = p, uco_role = r
|
|
| 918 | - , uco_lty = t1, uco_rty = t2, uco_deps = deps })
|
|
| 919 | - = ((((mkUnivCo $! p) $! go_cos deps) $! r) $!
|
|
| 920 | - (go_ty t1)) $! (go_ty t2)
|
|
| 921 | - go (SymCo co) = mkSymCo $! (go co)
|
|
| 922 | - go (TransCo co1 co2) = (mkTransCo $! (go co1)) $! (go co2)
|
|
| 923 | - go (SelCo d co) = mkSelCo d $! (go co)
|
|
| 924 | - go (LRCo lr co) = mkLRCo lr $! (go co)
|
|
| 925 | - go (InstCo co arg) = (mkInstCo $! (go co)) $! go arg
|
|
| 926 | - go (KindCo co) = mkKindCo $! (go co)
|
|
| 927 | - go (SubCo co) = mkSubCo $! (go co)
|
|
| 928 | - |
|
| 929 | - go_cos cos = let cos' = map go cos
|
|
| 930 | - in cos' `seqList` cos'
|
|
| 931 | --}
|
|
| 932 | - |
|
| 933 | 854 | -- | Perform a substitution within a 'DVarSet' of free variables,
|
| 934 | 855 | -- returning the free coercion variables.
|
| 935 | 856 | substDCoVarSet :: Subst -> DCoVarSet -> DCoVarSet
|
| ... | ... | @@ -256,13 +256,13 @@ import {-# SOURCE #-} GHC.Tc.Utils.TcType ( isConcreteTyVar ) |
| 256 | 256 | import GHC.Utils.Misc
|
| 257 | 257 | import GHC.Utils.Outputable
|
| 258 | 258 | import GHC.Utils.Panic
|
| 259 | -import GHC.Data.FastString
|
|
| 259 | +import GHC.Utils.StrictIdentity
|
|
| 260 | 260 | |
| 261 | +import GHC.Data.FastString
|
|
| 261 | 262 | import GHC.Data.Maybe ( orElse, isJust )
|
| 262 | 263 | import GHC.List (build)
|
| 263 | 264 | |
| 264 | 265 | import qualified Data.Monoid as M
|
| 265 | -import Data.Functor.Identity
|
|
| 266 | 266 | |
| 267 | 267 | -- $type_classification
|
| 268 | 268 | -- #type_classification#
|
| ... | ... | @@ -483,9 +483,9 @@ expandTypeSynonyms ty |
| 483 | 483 | expandTypeSynonymsX :: Subst -> Type -> Type
|
| 484 | 484 | expandTypeSynonymsX
|
| 485 | 485 | = case mapTyCoX expandTypeSynonymMapper of
|
| 486 | - (exp_ty, _, _, _) -> \subst ty -> runIdentity (exp_ty subst ty)
|
|
| 486 | + (exp_ty, _, _, _) -> \subst ty -> runStrictIdentity (exp_ty subst ty)
|
|
| 487 | 487 | |
| 488 | -expandTypeSynonymMapper :: TyCoMapper Subst Identity
|
|
| 488 | +expandTypeSynonymMapper :: TyCoMapper Subst StrictIdentity
|
|
| 489 | 489 | -- Just like substitution, but treat TyConApp specially
|
| 490 | 490 | expandTypeSynonymMapper
|
| 491 | 491 | = substTyCoMapper { tcm_tcapp_ty = tcapp_ty }
|
| 1 | +-- |
|
|
| 2 | +-- Module : GHC.Utils.StrictIdentity
|
|
| 3 | +-- License : BSD-style (see the file LICENSE)
|
|
| 4 | +--
|
|
| 5 | +-- The /strict/ identity functor and monad.
|
|
| 6 | +--
|
|
| 7 | +-- This trivial type constructor serves two purposes:
|
|
| 8 | +--
|
|
| 9 | +-- * It can be used with functions parameterized by functor or monad classes.
|
|
| 10 | +--
|
|
| 11 | +-- * It can be used as a base monad to which a series of monad
|
|
| 12 | +-- transformers may be applied to construct a composite monad.
|
|
| 13 | +-- Most monad transformer modules include the special case of
|
|
| 14 | +-- applying the transformer to 'Identity'. For example, @State s@
|
|
| 15 | +-- is an abbreviation for @StateT s 'Identity'@.
|
|
| 16 | + |
|
| 17 | +-----------------------------------------------------------------------------
|
|
| 18 | + |
|
| 19 | +module GHC.Utils.StrictIdentity (
|
|
| 20 | + StrictIdentity(..)
|
|
| 21 | + ) where
|
|
| 22 | + |
|
| 23 | +import GHC.Prelude
|
|
| 24 | + |
|
| 25 | +import Data.Coerce( coerce )
|
|
| 26 | + |
|
| 27 | +newtype StrictIdentity a = StrictIdentity { runStrictIdentity :: a }
|
|
| 28 | + |
|
| 29 | +-----------------------------------------------------------------------------
|
|
| 30 | +-- In the following instances, the key lines are the strict applications ($!)
|
|
| 31 | +-----------------------------------------------------------------------------
|
|
| 32 | + |
|
| 33 | +instance Functor StrictIdentity where
|
|
| 34 | + fmap f (StrictIdentity x) = StrictIdentity (f $! x)
|
|
| 35 | + |
|
| 36 | +instance Applicative StrictIdentity where
|
|
| 37 | + pure = StrictIdentity
|
|
| 38 | + (StrictIdentity f) <*> (StrictIdentity x) = StrictIdentity (f $! x)
|
|
| 39 | + |
|
| 40 | +instance Monad StrictIdentity where
|
|
| 41 | + m >>= k = k $! (runStrictIdentity m) |
| ... | ... | @@ -1029,6 +1029,7 @@ Library |
| 1029 | 1029 | GHC.Utils.Panic.Plain
|
| 1030 | 1030 | GHC.Utils.Ppr
|
| 1031 | 1031 | GHC.Utils.Ppr.Colour
|
| 1032 | + GHC.Utils.StrictIdentity
|
|
| 1032 | 1033 | GHC.Utils.TmpFs
|
| 1033 | 1034 | GHC.Utils.Touch
|
| 1034 | 1035 | GHC.Utils.Trace
|