@@ -20,6 +20,7 @@ module Language.PureScript.TypeChecker.Entailment (
2020import Data.Function (on )
2121import Data.List
2222import Data.Maybe (maybeToList )
23+ import Data.Foldable (foldMap )
2324import qualified Data.Map as M
2425
2526import Control.Applicative
@@ -199,13 +200,35 @@ entails env moduleName context = solve (sortedNubBy canonicalizeDictionary (filt
199200-- and return a substitution from type variables to types which makes the type heads unify.
200201--
201202typeHeadsAreEqual :: ModuleName -> Environment -> Type -> Type -> Maybe [(String , Type )]
202- typeHeadsAreEqual _ _ (Skolem _ s1 _) (Skolem _ s2 _) | s1 == s2 = Just []
203- typeHeadsAreEqual _ _ t (TypeVar v) = Just [(v, t)]
203+ typeHeadsAreEqual _ _ (Skolem _ s1 _) (Skolem _ s2 _) | s1 == s2 = Just []
204+ typeHeadsAreEqual _ _ t (TypeVar v) = Just [(v, t)]
205+ -- In this case, we might want type information to flow back to the typechecker.
206+ -- TODO: run this function in the UnifyT monad.
207+ typeHeadsAreEqual _ _ (TUnknown _) _ = Just []
204208typeHeadsAreEqual _ _ (TypeConstructor c1) (TypeConstructor c2) | c1 == c2 = Just []
205- typeHeadsAreEqual m e (TypeApp h1 t1) (TypeApp h2 t2) = (++) <$> typeHeadsAreEqual m e h1 h2 <*> typeHeadsAreEqual m e t1 t2
209+ typeHeadsAreEqual m e (TypeApp h1 t1) (TypeApp h2 t2) = (++) <$> typeHeadsAreEqual m e h1 h2
210+ <*> typeHeadsAreEqual m e t1 t2
206211typeHeadsAreEqual m e (SaturatedTypeSynonym name args) t2 = case expandTypeSynonym' e name args of
207212 Left _ -> Nothing
208213 Right t1 -> typeHeadsAreEqual m e t1 t2
214+ typeHeadsAreEqual _ _ REmpty REmpty = Just []
215+ typeHeadsAreEqual m e r1@ (RCons _ _ _) r2@ (RCons _ _ _) =
216+ let (s1, r1') = rowToList r1
217+ (s2, r2') = rowToList r2
218+
219+ int = [ (t1, t2) | (name, t1) <- s1, (name', t2) <- s2, name == name' ]
220+ sd1 = [ (name, t1) | (name, t1) <- s1, name `notElem` map fst s2 ]
221+ sd2 = [ (name, t2) | (name, t2) <- s2, name `notElem` map fst s1 ]
222+ in (++) <$> foldMap (\ (t1, t2) -> typeHeadsAreEqual m e t1 t2) int
223+ <*> go sd1 r1' sd2 r2'
224+ where
225+ go :: [(String , Type )] -> Type -> [(String , Type )] -> Type -> Maybe [(String , Type )]
226+ go [] REmpty [] REmpty = Just []
227+ go [] (TUnknown _) _ _ = Just []
228+ go [] (TypeVar v1) [] (TypeVar v2) | v1 == v2 = Just []
229+ go [] (Skolem _ s1 _) [] (Skolem _ s2 _) | s1 == s2 = Just []
230+ go sd r [] (TypeVar v) = Just [(v, rowFromList (sd, r))]
231+ go _ _ _ _ = Nothing
209232typeHeadsAreEqual _ _ _ _ = Nothing
210233
211234-- |
0 commit comments