@@ -57,6 +57,7 @@ instance Unifiable Type where
57 apply s (Object r) = Object (apply s r)
57 apply s (Object r) = Object (apply s r)
58 apply s (Function args ret) = Function (map (apply s) args) (apply s ret)
58 apply s (Function args ret) = Function (map (apply s) args) (apply s ret)
59 apply s (TypeApp t1 t2) = TypeApp (apply s t1) (apply s t2)
59 apply s (TypeApp t1 t2) = TypeApp (apply s t1) (apply s t2)
60+ apply s (RCons name ty r) = RCons name (apply s ty) (apply s r)
60 apply _ t = t
61 apply _ t = t
61 unknowns (TUnknown (Unknown u)) = [u]
62 unknowns (TUnknown (Unknown u)) = [u]
62 unknowns (SaturatedTypeSynonym _ tys) = concatMap unknowns tys
63 unknowns (SaturatedTypeSynonym _ tys) = concatMap unknowns tys
@@ -65,40 +66,6 @@ instance Unifiable Type where
65 unknowns (Object r) = unknowns r
66 unknowns (Object r) = unknowns r
66 unknowns (Function args ret) = concatMap unknowns args ++ unknowns ret
67 unknowns (Function args ret) = concatMap unknowns args ++ unknowns ret
67 unknowns (TypeApp t1 t2) = unknowns t1 ++ unknowns t2
68 unknowns (TypeApp t1 t2) = unknowns t1 ++ unknowns t2
70−instance Unifiable Row where
72− isUnknown (RUnknown u) = Just u
73− isUnknown _ = Nothing
76− (s1, r1') = rowToList r1
77− (s2, r2') = rowToList r2
78− int = [ (t1, t2) | (name, t1) <- s1, (name', t2) <- s2, name == name' ]
79− sd1 = [ (name, t1) | (name, t1) <- s1, name `notElem` map fst s2 ]
80− sd2 = [ (name, t2) | (name, t2) <- s2, name `notElem` map fst s1 ]
82− forM_ int (uncurry (~~))
83− unifyRows sd1 r1' sd2 r2'
85− unifyRows :: [(String, Type)] -> Row -> [(String, Type)] -> Row -> Subst ()
86− unifyRows [] (RUnknown u) sd r = replace u (rowFromList (sd, r))
87− unifyRows sd r [] (RUnknown u) = replace u (rowFromList (sd, r))
88− unifyRows ((name, ty):row) r others u@(RUnknown un) = do
90− forM row $ \(_, t) -> occursCheck un t
92− u ~~ RCons name ty u'
93− unifyRows row r others u'
94− unifyRows [] REmpty [] REmpty = return ()
95− unifyRows [] (RowVar v1) [] (RowVar v2) | v1 == v2 = return ()
96− unifyRows [] (RSkolem s1) [] (RSkolem s2) | s1 == s2 = return ()
97− unifyRows sd3 r3 sd4 r4 = throwError $ "Cannot unify " ++ prettyPrintRow (rowFromList (sd3, r3)) ++ " with " ++ prettyPrintRow (rowFromList (sd4, r4)) ++ "."
98− apply s (RUnknown u) = runSubstitution s u
99− apply s (RCons name ty r) = RCons name (apply s ty) (apply s r)
101− unknowns (RUnknown (Unknown u)) = [u]
102 unknowns (RCons _ ty r) = unknowns ty ++ unknowns r
69 unknowns (RCons _ ty r) = unknowns ty ++ unknowns r
103 unknowns _ = []
70 unknowns _ = []
@@ -141,8 +108,38 @@ unifyTypes t1 t2 = rethrow (\e -> "Error unifying type " ++ prettyPrintType t1 +
141 t3 `unifyTypes` t5
108 t3 `unifyTypes` t5
142 t4 `unifyTypes` t6
109 t4 `unifyTypes` t6
143 unifyTypes' (Skolem s1) (Skolem s2) | s1 == s2 = return ()
110 unifyTypes' (Skolem s1) (Skolem s2) | s1 == s2 = return ()
111+ unifyTypes' r1@(RCons _ _ _) r2 = unifyRows r1 r2
112+ unifyTypes' r1 r2@(RCons _ _ _) = unifyRows r1 r2
113+ unifyTypes' r1@REmpty r2 = unifyRows r1 r2
114+ unifyTypes' r1 r2@REmpty = unifyRows r1 r2
144 unifyTypes' t3 t4 = throwError $ "Cannot unify " ++ prettyPrintType t3 ++ " with " ++ prettyPrintType t4 ++ "."
115 unifyTypes' t3 t4 = throwError $ "Cannot unify " ++ prettyPrintType t3 ++ " with " ++ prettyPrintType t4 ++ "."
117+unifyRows :: Type -> Type -> Subst ()
120+ (s1, r1') = rowToList r1
121+ (s2, r2') = rowToList r2
122+ int = [ (t1, t2) | (name, t1) <- s1, (name', t2) <- s2, name == name' ]
123+ sd1 = [ (name, t1) | (name, t1) <- s1, name `notElem` map fst s2 ]
124+ sd2 = [ (name, t2) | (name, t2) <- s2, name `notElem` map fst s1 ]
126+ forM_ int (uncurry (~~))
127+ unifyRows' sd1 r1' sd2 r2'
129+ unifyRows' :: [(String, Type)] -> Type -> [(String, Type)] -> Type -> Subst ()
130+ unifyRows' [] (TUnknown u) sd r = replace u (rowFromList (sd, r))
131+ unifyRows' sd r [] (TUnknown u) = replace u (rowFromList (sd, r))
132+ unifyRows' ((name, ty):row) r others u@(TUnknown un) = do
134+ forM row $ \(_, t) -> occursCheck un t
136+ u ~~ RCons name ty u'
137+ unifyRows' row r others u'
138+ unifyRows' [] REmpty [] REmpty = return ()
139+ unifyRows' [] (TypeVar v1) [] (TypeVar v2) | v1 == v2 = return ()
140+ unifyRows' [] (Skolem s1) [] (Skolem s2) | s1 == s2 = return ()
141+ unifyRows' sd3 r3 sd4 r4 = throwError $ "Cannot unify " ++ prettyPrintRow (rowFromList (sd3, r3)) ++ " with " ++ prettyPrintRow (rowFromList (sd4, r4)) ++ "."
146typeConstructorsAreEqual :: Environment -> ModuleName -> Qualified ProperName -> Qualified ProperName -> Bool
143typeConstructorsAreEqual :: Environment -> ModuleName -> Qualified ProperName -> Qualified ProperName -> Bool
147typeConstructorsAreEqual env moduleName c1 c2 =
144typeConstructorsAreEqual env moduleName c1 c2 =
@@ -198,16 +195,14 @@ escapeCheck checks ty sub =
199skolemEscapeCheck :: Type -> Check ()
196skolemEscapeCheck :: Type -> Check ()
200skolemEscapeCheck ty =
197skolemEscapeCheck ty =
201− case something (extQ (mkQ Nothing findSkolems) findRSkolems) ty of
198+ case something (mkQ Nothing findSkolems) ty of
202 Nothing -> return ()
199 Nothing -> return ()
203 Just _ -> throwError "Skolem variables cannot escape. Consider adding a type signature."
200 Just _ -> throwError "Skolem variables cannot escape. Consider adding a type signature."
205 findSkolems (Skolem _) = return ()
202 findSkolems (Skolem _) = return ()
206 findSkolems _ = mzero
203 findSkolems _ = mzero
207− findRSkolems (RSkolem _) = return ()
208− findRSkolems _ = mzero
210−setify :: Row -> Row
205+setify :: Type -> Type
211setify = rowFromList . first (M.toList . M.fromList) . rowToList
206setify = rowFromList . first (M.toList . M.fromList) . rowToList
213setifyAll :: (D.Data d) => d -> d
208setifyAll :: (D.Data d) => d -> d
@@ -217,13 +212,10 @@ varIfUnknown :: Type -> Type
217varIfUnknown ty =
212varIfUnknown ty =
218 let unks = nub $ unknowns ty
213 let unks = nub $ unknowns ty
219 toName = (:) 't' . show
214 toName = (:) 't' . show
220− ty' = everywhere (mkT rowToVar) . everywhere (mkT typeToVar) $ ty
215+ ty' = everywhere (mkT typeToVar) $ ty
221 typeToVar :: Type -> Type
216 typeToVar :: Type -> Type
222 typeToVar (TUnknown (Unknown u)) = TypeVar (toName u)
217 typeToVar (TUnknown (Unknown u)) = TypeVar (toName u)
223 typeToVar t = t
218 typeToVar t = t
224− rowToVar :: Row -> Row
225− rowToVar (RUnknown (Unknown u)) = RowVar (toName u)
227 in mkForAll (sort . map toName $ unks) ty'
219 in mkForAll (sort . map toName $ unks) ty'
229replaceAllTypeVars :: (D.Data d) => [(String, Type)] -> d -> d
221replaceAllTypeVars :: (D.Data d) => [(String, Type)] -> d -> d
@@ -237,12 +229,6 @@ replaceTypeVars name t = everywhereBut (mkQ False isShadowed) (mkT replaceTypeVa
237 isShadowed (ForAll v _) | v == name = True
229 isShadowed (ForAll v _) | v == name = True
238 isShadowed _ = False
230 isShadowed _ = False
240−replaceRowVars :: (D.Data d) => String -> Row -> d -> d
241−replaceRowVars name r = everywhere (mkT replaceRowVar)
243− replaceRowVar (RowVar v) | v == name = r
244− replaceRowVar other = other
246replaceAllVarsWithUnknowns :: Type -> Subst Type
232replaceAllVarsWithUnknowns :: Type -> Subst Type
247replaceAllVarsWithUnknowns (ForAll ident ty) = replaceVarWithUnknown ident ty >>= replaceAllVarsWithUnknowns
233replaceAllVarsWithUnknowns (ForAll ident ty) = replaceVarWithUnknown ident ty >>= replaceAllVarsWithUnknowns
248replaceAllVarsWithUnknowns ty = return ty
234replaceAllVarsWithUnknowns ty = return ty
@@ -250,8 +236,7 @@ replaceAllVarsWithUnknowns ty = return ty
250replaceVarWithUnknown :: String -> Type -> Subst Type
236replaceVarWithUnknown :: String -> Type -> Subst Type
251replaceVarWithUnknown ident ty = do
237replaceVarWithUnknown ident ty = do
252 tu <- fresh
238 tu <- fresh
254− return $ replaceRowVars ident ru . replaceTypeVars ident tu $ ty
239+ return $ replaceTypeVars ident tu $ ty
256replaceAllTypeSynonyms :: (Functor m, MonadState CheckState m, MonadReader SubstContext m, MonadError String m) => (D.Data d) => d -> m d
241replaceAllTypeSynonyms :: (Functor m, MonadState CheckState m, MonadReader SubstContext m, MonadError String m) => (D.Data d) => d -> m d
257replaceAllTypeSynonyms d = do
242replaceAllTypeSynonyms d = do
@@ -488,7 +473,7 @@ inferBinder val (ObjectBinder props) = do
488 val ~~ Object row
473 val ~~ Object row
489 return m1
474 return m1
491− inferRowProperties :: Row -> Row -> [(String, Binder)] -> Subst (M.Map Ident Type)
476+ inferRowProperties :: Type -> Type -> [(String, Binder)] -> Subst (M.Map Ident Type)
492 inferRowProperties nrow row [] = nrow ~~ row >> return M.empty
477 inferRowProperties nrow row [] = nrow ~~ row >> return M.empty
493 inferRowProperties nrow row ((name, binder):binders) = do
478 inferRowProperties nrow row ((name, binder):binders) = do
494 propTy <- fresh
479 propTy <- fresh
@@ -598,8 +583,7 @@ checkBlock mass ret (s:ss) = do
598skolemize :: String -> Type -> Subst Type
583skolemize :: String -> Type -> Subst Type
599skolemize ident ty = do
584skolemize ident ty = do
600 tsk <- Skolem <$> fresh'
585 tsk <- Skolem <$> fresh'
601− rsk <- RSkolem <$> fresh'
602− return $ replaceRowVars ident rsk $ replaceTypeVars ident tsk ty
586+ return $ replaceTypeVars ident tsk ty
604check :: Value -> Type -> Subst ()
588check :: Value -> Type -> Subst ()
605check val ty = rethrow errorMessage $ check' val ty
589check val ty = rethrow errorMessage $ check' val ty
@@ -684,15 +668,15 @@ check' val (SaturatedTypeSynonym name args) = do
684 check val ty
668 check val ty
685check' val ty = throwError $ prettyPrintValue val ++ " does not have type " ++ prettyPrintType ty
669check' val ty = throwError $ prettyPrintValue val ++ " does not have type " ++ prettyPrintType ty
687−checkProperties :: [(String, Value)] -> Row -> Bool -> Subst ()
671+checkProperties :: [(String, Value)] -> Type -> Bool -> Subst ()
688checkProperties ps row lax = let (ts, r') = rowToList row in go ps ts r' where
672checkProperties ps row lax = let (ts, r') = rowToList row in go ps ts r' where
689 go [] [] REmpty = return ()
673 go [] [] REmpty = return ()
690− go [] [] u@(RUnknown _) = u ~~ REmpty
674+ go [] [] u@(TUnknown _) = u ~~ REmpty
691− go [] [] (RSkolem _) | lax = return ()
675+ go [] [] (Skolem _) | lax = return ()
692 go [] ((p, _): _) _ | lax = return ()
676 go [] ((p, _): _) _ | lax = return ()
693 | otherwise = throwError $ prettyPrintValue (ObjectLiteral ps) ++ " does not have property " ++ p
677 | otherwise = throwError $ prettyPrintValue (ObjectLiteral ps) ++ " does not have property " ++ p
694 go ((p,_):_) [] REmpty = throwError $ "Property " ++ p ++ " is not present in closed object type " ++ prettyPrintRow row
678 go ((p,_):_) [] REmpty = throwError $ "Property " ++ p ++ " is not present in closed object type " ++ prettyPrintRow row
695− go ((p,v):ps') [] u@(RUnknown _) = do
679+ go ((p,v):ps') [] u@(TUnknown _) = do
696 ty <- infer v
680 ty <- infer v
697 rest <- fresh
681 rest <- fresh
698 u ~~ RCons p ty rest
682 u ~~ RCons p ty rest