@@ -22,7 +22,7 @@ import Data.List
22import Data.Maybe (isJust, fromMaybe)
22import Data.Maybe (isJust, fromMaybe)
23import Data.Function
23import Data.Function
24import qualified Data.Data as D
24import qualified Data.Data as D
25−import Data.Generics (everywhere, everywhereM, everything, mkT, mkM, mkQ, extM, extQ)
25+import Data.Generics (everywhere, everywhereM, everything, everywhereBut, mkT, mkM, mkQ, extM, extQ)
27import Language.PureScript.Values
27import Language.PureScript.Values
28import Language.PureScript.Types
28import Language.PureScript.Types
@@ -185,27 +185,27 @@ setifyAll = everywhere (mkT setify)
185varIfUnknown :: Type -> Type
185varIfUnknown :: Type -> Type
186varIfUnknown ty = mkForAll (sort . map ((:) 'u' . show) . nub $ unknowns ty) ty
186varIfUnknown ty = mkForAll (sort . map ((:) 'u' . show) . nub $ unknowns ty) ty
188−replaceTypeVars :: M.Map String Type -> Type -> Type
188+replaceAllTypeVars :: (D.Data d) => [(String, Type)] -> d -> d
189+replaceAllTypeVars = foldl' (\f (name, ty) -> replaceTypeVars name ty . f) id
191+replaceTypeVars :: (D.Data d) => String -> Type -> d -> d
189−replaceTypeVars m = everywhere (mkT replace)
192+replaceTypeVars name t = everywhereBut (mkQ False isShadowed) (mkT replace)
191− replace (TypeVar v) = case M.lookup v m of
194+ replace (TypeVar v) | v == name = t
194 replace t = t
195 replace t = t
196+ isShadowed (ForAll v _) | v == name = True
197+ isShadowed _ = False
196−replaceRowVars :: M.Map String Row -> Type -> Type
199+replaceRowVars :: (D.Data d) => String -> Row -> d -> d
197−replaceRowVars m = everywhere (mkT replace)
200+replaceRowVars name r = everywhere (mkT replace)
199− replace (RowVar v) = case M.lookup v m of
202+ replace (RowVar v) | v == name = r
202 replace t = t
203 replace t = t
204replaceAllVarsWithUnknowns :: Type -> Subst Check Type
205replaceAllVarsWithUnknowns :: Type -> Subst Check Type
205replaceAllVarsWithUnknowns (ForAll ident ty) = replaceVarsWithUnknowns [ident] ty >>= replaceAllVarsWithUnknowns
206replaceAllVarsWithUnknowns (ForAll ident ty) = replaceVarsWithUnknowns [ident] ty >>= replaceAllVarsWithUnknowns
206replaceAllVarsWithUnknowns ty = return ty
207replaceAllVarsWithUnknowns ty = return ty
208−-- TODO: need to be careful inside a forall, since variables might be renamed
209replaceVarsWithUnknowns :: [String] -> Type -> Subst Check Type
209replaceVarsWithUnknowns :: [String] -> Type -> Subst Check Type
210replaceVarsWithUnknowns idents = flip evalStateT M.empty . everywhereM (flip extM f $ mkM g)
210replaceVarsWithUnknowns idents = flip evalStateT M.empty . everywhereM (flip extM f $ mkM g)
@@ -251,9 +251,7 @@ expandTypeSynonym name args = do
251 env <- lift getEnv
251 env <- lift getEnv
252 modulePath <- checkModulePath `fmap` lift get
252 modulePath <- checkModulePath `fmap` lift get
253 case M.lookup (qualify modulePath name) (typeSynonyms env) of
253 case M.lookup (qualify modulePath name) (typeSynonyms env) of
254− Just (synArgs, body) -> do
254+ Just (synArgs, body) -> return $ replaceAllTypeVars (zip synArgs args) body
255− let m = M.fromList $ zip synArgs args
256− return $ replaceTypeVars m body
257 Nothing -> error "Type synonym was not defined"
255 Nothing -> error "Type synonym was not defined"
259ensureNoDuplicateProperties :: [(String, Value)] -> Check ()
257ensureNoDuplicateProperties :: [(String, Value)] -> Check ()
@@ -581,7 +579,7 @@ skolemize :: String -> Type -> Subst Check Type
581skolemize ident ty = do
579skolemize ident ty = do
582 tsk <- Skolem <$> fresh'
580 tsk <- Skolem <$> fresh'
583 rsk <- RSkolem <$> fresh'
581 rsk <- RSkolem <$> fresh'
584− return $ replaceRowVars (M.singleton ident rsk) $ replaceTypeVars (M.singleton ident tsk) ty
582+ return $ replaceRowVars ident rsk $ replaceTypeVars ident tsk ty
586check :: M.Map Ident Type -> Value -> Type -> Subst Check ()
584check :: M.Map Ident Type -> Value -> Type -> Subst Check ()
587check m val ty = rethrow errorMessage $ check' m val ty
585check m val ty = rethrow errorMessage $ check' m val ty