@@ -12,13 +12,16 @@ module Wingman.Judgements.Theta
1212
1313import Class (classTyVars )
1414import Control.Applicative (empty )
15+ import Control.Lens (preview )
1516import Data.Maybe (fromMaybe , mapMaybe , maybeToList )
17+ import Data.Generics.Sum (_Ctor )
1618import Data.Set (Set )
1719import qualified Data.Set as S
1820import Development.IDE.Core.UseStale
1921import Development.IDE.GHC.Compat
20- import Generics.SYB hiding (tyConName , empty )
21- import GhcPlugins (mkVarOcc , splitTyConApp_maybe , getTyVar_maybe , zipTvSubst )
22+ import Generics.SYB hiding (tyConName , empty , Generic )
23+ import GHC.Generics
24+ import GhcPlugins (mkVarOcc , splitTyConApp_maybe , getTyVar_maybe , zipTvSubst , unionTCvSubst , emptyTCvSubst , TCvSubst )
2225#if __GLASGOW_HASKELL__ > 806
2326import GhcPlugins (eqTyCon )
2427#else
@@ -40,7 +43,7 @@ data Evidence
4043 = EqualityOfTypes Type Type
4144 -- | We have an instance in scope
4245 | HasInstance PredType
43- deriving (Show )
46+ deriving (Show , Generic )
4447
4548
4649------------------------------------------------------------------------------
@@ -75,21 +78,46 @@ getEvidenceAtHole (unTrack -> dst)
7578 . unTrack
7679
7780
78- ------------------------------------------------------------------------------
79- -- | Update our knowledge of which types are equal.
80- evidenceToSubst :: Evidence -> TacticState -> TacticState
81- evidenceToSubst (EqualityOfTypes a b) ts =
81+ mkSubst :: Set TyVar -> Type -> Type -> TCvSubst
82+ mkSubst skolems a b =
8283 let tyvars = S. fromList $ mapMaybe getTyVar_maybe [a, b]
8384 -- If we can unify our skolems, at least one is no longer a skolem.
8485 -- Removing them from this set ensures we can get a subtitution between
8586 -- the two. But it's okay to leave them in 'ts_skolems' in general, since
8687 -- they won't exist after running this substitution.
87- skolems = ts_skolems ts S. \\ tyvars
88+ skolems' = skolems S. \\ tyvars
8889 in
89- case tryUnifyUnivarsButNotSkolems skolems (CType a) (CType b) of
90- Just subst -> updateSubst subst ts
91- Nothing -> ts
92- evidenceToSubst HasInstance {} ts = ts
90+ case tryUnifyUnivarsButNotSkolems skolems' (CType a) (CType b) of
91+ Just subst -> subst
92+ Nothing -> emptyTCvSubst
93+
94+
95+ substPair :: TCvSubst -> (Type , Type ) -> (Type , Type )
96+ substPair subst (ty, ty') = (substTy subst ty, substTy subst ty')
97+
98+
99+ ------------------------------------------------------------------------------
100+ -- | Construct a substitution given a list of types that are equal to one
101+ -- another. This is more subtle than it seems, since there might be several
102+ -- equalities for the same type. We must be careful to push the accumulating
103+ -- substitution through each pair of types before adding their equalities.
104+ allEvidenceToSubst :: Set TyVar -> [(Type , Type )] -> TCvSubst
105+ allEvidenceToSubst _ [] = emptyTCvSubst
106+ allEvidenceToSubst skolems ((a, b) : evs) =
107+ let subst = mkSubst skolems a b
108+ in unionTCvSubst subst
109+ $ allEvidenceToSubst skolems
110+ $ fmap (substPair subst) evs
111+
112+ ------------------------------------------------------------------------------
113+ -- | Update our knowledge of which types are equal.
114+ evidenceToSubst :: [Evidence ] -> TacticState -> TacticState
115+ evidenceToSubst evs ts =
116+ updateSubst
117+ (allEvidenceToSubst (ts_skolems ts)
118+ $ mapMaybe (preview $ _Ctor @ " EqualityOfTypes" )
119+ $ evs)
120+ ts
93121
94122
95123------------------------------------------------------------------------------
0 commit comments