@@ -22,7 +22,7 @@ import Data.List
2222import Data.Maybe (isJust, fromMaybe)
2323import Data.Function
2424import 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)
2626
2727import Language.PureScript.Values
2828import Language.PureScript.Types
@@ -185,27 +185,27 @@ setifyAll = everywhere (mkT setify)
185185varIfUnknown :: Type -> Type
186186varIfUnknown ty = mkForAll (sort . map ((:) 'u' . show) . nub $ unknowns ty) ty
187187
188−replaceTypeVars :: M.Map String Type -> Type -> Type
189−replaceTypeVars m = everywhere (mkT replace)
188+replaceAllTypeVars :: (D.Data d) => [(String, Type)] -> d -> d
189+replaceAllTypeVars = foldl' (\f (name, ty) -> replaceTypeVars name ty . f) id
190+
191+replaceTypeVars :: (D.Data d) => String -> Type -> d -> d
192+replaceTypeVars name t = everywhereBut (mkQ False isShadowed) (mkT replace)
190193 where
191− replace (TypeVar v) = case M.lookup v m of
192− Just ty -> ty
193− _ -> TypeVar v
194+ replace (TypeVar v) | v == name = t
194195 replace t = t
196+ isShadowed (ForAll v _) | v == name = True
197+ isShadowed _ = False
195198
196−replaceRowVars :: M.Map String Row -> Type -> Type
197−replaceRowVars m = everywhere (mkT replace)
199+replaceRowVars :: (D.Data d) => String -> Row -> d -> d
200+replaceRowVars name r = everywhere (mkT replace)
198201 where
199− replace (RowVar v) = case M.lookup v m of
200− Just r -> r
201− _ -> RowVar v
202+ replace (RowVar v) | v == name = r
202203 replace t = t
203204
204205replaceAllVarsWithUnknowns :: Type -> Subst Check Type
205206replaceAllVarsWithUnknowns (ForAll ident ty) = replaceVarsWithUnknowns [ident] ty >>= replaceAllVarsWithUnknowns
206207replaceAllVarsWithUnknowns ty = return ty
207208
208−-- TODO: need to be careful inside a forall, since variables might be renamed
209209replaceVarsWithUnknowns :: [String] -> Type -> Subst Check Type
210210replaceVarsWithUnknowns idents = flip evalStateT M.empty . everywhereM (flip extM f $ mkM g)
211211 where
@@ -251,9 +251,7 @@ expandTypeSynonym name args = do
251251 env <- lift getEnv
252252 modulePath <- checkModulePath `fmap` lift get
253253 case M.lookup (qualify modulePath name) (typeSynonyms env) of
254− Just (synArgs, body) -> do
255− let m = M.fromList $ zip synArgs args
256− return $ replaceTypeVars m body
254+ Just (synArgs, body) -> return $ replaceAllTypeVars (zip synArgs args) body
257255 Nothing -> error "Type synonym was not defined"
258256
259257ensureNoDuplicateProperties :: [(String, Value)] -> Check ()
@@ -581,7 +579,7 @@ skolemize :: String -> Type -> Subst Check Type
581579skolemize ident ty = do
582580 tsk <- Skolem <$> fresh'
583581 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
585583
586584check :: M.Map Ident Type -> Value -> Type -> Subst Check ()
587585check m val ty = rethrow errorMessage $ check' m val ty