@@ -65,7 +65,7 @@ typeOf name val = do
65 solution <- solveTypeConstraints desugared emptyTypeSolution
65 solution <- solveTypeConstraints desugared emptyTypeSolution
66 let ty = fst (runTypeSolution solution) n
66 let ty = fst (runTypeSolution solution) n
67 allUnknownsBecameQuantified desugared solution ty
67 allUnknownsBecameQuantified desugared solution ty
68− return $ varIfUnknown ty
68+ return $ varIfUnknown $ desaturateAllTypeSynonyms ty
70allUnknownsBecameQuantified :: [TypeConstraint] -> TypeSolution -> Type -> Check ()
70allUnknownsBecameQuantified :: [TypeConstraint] -> TypeSolution -> Type -> Check ()
71allUnknownsBecameQuantified cs solution ty = do
71allUnknownsBecameQuantified cs solution ty = do
@@ -133,6 +133,14 @@ varIfUnknown ty =
133 Just name -> return $ RowVar name
133 Just name -> return $ RowVar name
134 g r = return r
134 g r = return r
136+replaceTypeVars :: M.Map String Type -> Type -> Type
137+replaceTypeVars m = everywhere (mkT replace)
139+ replace (TypeVar v) = case M.lookup v m of
136replaceVarsWithUnknowns :: [String] -> Type -> Check Type
144replaceVarsWithUnknowns :: [String] -> Type -> Check Type
137replaceVarsWithUnknowns idents = flip evalStateT M.empty . everywhereM (flip extM f $ mkM g)
145replaceVarsWithUnknowns idents = flip evalStateT M.empty . everywhereM (flip extM f $ mkM g)
@@ -158,14 +166,16 @@ replaceVarsWithUnknowns idents = flip evalStateT M.empty . everywhereM (flip ext
158 g r = return r
166 g r = return r
160replaceAllTypeSynonyms :: (D.Data d) => d -> Check d
168replaceAllTypeSynonyms :: (D.Data d) => d -> Check d
161−replaceAllTypeSynonyms ty = do
169+replaceAllTypeSynonyms d = do
162 env <- getEnv
170 env <- getEnv
163− go (M.toList $ typeSynonyms env) ty
171+ let syns = map (\(name, (args, _)) -> (name, length args)) . M.toList $ typeSynonyms env
172+ either throwError return $ saturateAllTypeSynonyms syns d
174+desaturateAllTypeSynonyms :: (D.Data d) => d -> d
175+desaturateAllTypeSynonyms = everywhere (mkT $ replace)
165− go [] d = return d
177+ replace (SaturatedTypeSynonym name args) = foldl (\t arg -> TypeApp t arg) (TypeConstructor name) args
166− go ((name, (args, repl)):rest) d = do
178+ replace t = t
167− d' <- either throwError return (substituteTypeSynonym name args repl d)
170replaceType :: (D.Data d) => Int -> Type -> d -> d
180replaceType :: (D.Data d) => Int -> Type -> d -> d
171replaceType n t = everywhere (mkT go)
181replaceType n t = everywhere (mkT go)
@@ -521,6 +531,17 @@ unifyTypes (TUnknown u) t = do
521unifyTypes t (TUnknown u) = do
531unifyTypes t (TUnknown u) = do
522 typeOccursCheck u t
532 typeOccursCheck u t
523 return [TypeConstraint u t]
533 return [TypeConstraint u t]
534+unifyTypes (SaturatedTypeSynonym name1 args1) (SaturatedTypeSynonym name2 args2) | name1 == name2 =
535+ fmap concat $ zipWithM unifyTypes args1 args2
536+unifyTypes (SaturatedTypeSynonym name args) ty = do
538+ case M.lookup name (typeSynonyms env) of
539+ Just (synArgs, body) -> do
540+ let m = M.fromList $ zip synArgs args
541+ let replaced = replaceTypeVars m body
542+ unifyTypes replaced ty
543+ Nothing -> error "Type synonym was not defined"
544+unifyTypes ty s@(SaturatedTypeSynonym _ _) = unifyTypes s ty
524unifyTypes Number Number = return []
545unifyTypes Number Number = return []
525unifyTypes String String = return []
546unifyTypes String String = return []
526unifyTypes Boolean Boolean = return []
547unifyTypes Boolean Boolean = return []