@@ -65,7 +65,7 @@ typeOf name val = do
6565 solution <- solveTypeConstraints desugared emptyTypeSolution
6666 let ty = fst (runTypeSolution solution) n
6767 allUnknownsBecameQuantified desugared solution ty
68− return $ varIfUnknown ty
68+ return $ varIfUnknown $ desaturateAllTypeSynonyms ty
6969
7070allUnknownsBecameQuantified :: [TypeConstraint] -> TypeSolution -> Type -> Check ()
7171allUnknownsBecameQuantified cs solution ty = do
@@ -133,6 +133,14 @@ varIfUnknown ty =
133133 Just name -> return $ RowVar name
134134 g r = return r
135135
136+replaceTypeVars :: M.Map String Type -> Type -> Type
137+replaceTypeVars m = everywhere (mkT replace)
138+ where
139+ replace (TypeVar v) = case M.lookup v m of
140+ Just ty -> ty
141+ _ -> TypeVar v
142+ replace t = t
143+
136144replaceVarsWithUnknowns :: [String] -> Type -> Check Type
137145replaceVarsWithUnknowns idents = flip evalStateT M.empty . everywhereM (flip extM f $ mkM g)
138146 where
@@ -158,14 +166,16 @@ replaceVarsWithUnknowns idents = flip evalStateT M.empty . everywhereM (flip ext
158166 g r = return r
159167
160168replaceAllTypeSynonyms :: (D.Data d) => d -> Check d
161−replaceAllTypeSynonyms ty = do
169+replaceAllTypeSynonyms d = do
162170 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
173+
174+desaturateAllTypeSynonyms :: (D.Data d) => d -> d
175+desaturateAllTypeSynonyms = everywhere (mkT $ replace)
164176 where
165− go [] d = return d
166− go ((name, (args, repl)):rest) d = do
167− d' <- either throwError return (substituteTypeSynonym name args repl d)
168− go rest d'
177+ replace (SaturatedTypeSynonym name args) = foldl (\t arg -> TypeApp t arg) (TypeConstructor name) args
178+ replace t = t
169179
170180replaceType :: (D.Data d) => Int -> Type -> d -> d
171181replaceType n t = everywhere (mkT go)
@@ -521,6 +531,17 @@ unifyTypes (TUnknown u) t = do
521531unifyTypes t (TUnknown u) = do
522532 typeOccursCheck u t
523533 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
537+ env <- getEnv
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
524545unifyTypes Number Number = return []
525546unifyTypes String String = return []
526547unifyTypes Boolean Boolean = return []