@@ -19,12 +19,10 @@ module Language.PureScript.TypeChecker.Types (
21import Data.List
21import Data.List
22−import Data.Maybe (isJust, fromMaybe)
22+import Data.Maybe (fromMaybe)
24import qualified Data.Data as D
23import qualified Data.Data as D
25import Data.Generics
24import Data.Generics
26− (extT, something, everywhere, everywhereM, everything,
27− everywhereBut, mkT, mkM, mkQ, extM, extQ)
25+ (mkT, something, everywhere, everywhereBut, mkQ, extQ)
29import Language.PureScript.Values
27import Language.PureScript.Values
30import Language.PureScript.Types
28import Language.PureScript.Types
@@ -40,8 +38,7 @@ import Control.Monad.State
40import Control.Monad.Error
38import Control.Monad.Error
42import Control.Applicative
40import Control.Applicative
43−import Control.Arrow (Arrow(..), Kleisli(..), (***), (&&&), second)
41+import Control.Arrow (Arrow(..))
44−import qualified Control.Category as C
46import qualified Data.Map as M
43import qualified Data.Map as M
@@ -60,7 +57,7 @@ instance Unifiable Type where
60 apply _ t = t
57 apply _ t = t
61 unknowns (TUnknown (Unknown u)) = [u]
58 unknowns (TUnknown (Unknown u)) = [u]
62 unknowns (SaturatedTypeSynonym _ tys) = concatMap unknowns tys
59 unknowns (SaturatedTypeSynonym _ tys) = concatMap unknowns tys
63− unknowns (ForAll idents ty) = unknowns ty
60+ unknowns (ForAll _ ty) = unknowns ty
64 unknowns (Array t) = unknowns t
61 unknowns (Array t) = unknowns t
65 unknowns (Object r) = unknowns r
62 unknowns (Object r) = unknowns r
66 unknowns (Function args ret) = concatMap unknowns args ++ unknowns ret
63 unknowns (Function args ret) = concatMap unknowns args ++ unknowns ret
@@ -85,16 +82,16 @@ instance Unifiable Row where
85 unifyRows :: [(String, Type)] -> Row -> [(String, Type)] -> Row -> Subst ()
82 unifyRows :: [(String, Type)] -> Row -> [(String, Type)] -> Row -> Subst ()
86 unifyRows [] (RUnknown u) sd r = replace u (rowFromList (sd, r))
83 unifyRows [] (RUnknown u) sd r = replace u (rowFromList (sd, r))
87 unifyRows sd r [] (RUnknown u) = replace u (rowFromList (sd, r))
84 unifyRows sd r [] (RUnknown u) = replace u (rowFromList (sd, r))
88− unifyRows ns@((name, ty):row) r others u@(RUnknown un) = do
85+ unifyRows ((name, ty):row) r others u@(RUnknown un) = do
89 occursCheck un ty
86 occursCheck un ty
90− forM row $ \(_, ty) -> occursCheck un ty
87+ forM row $ \(_, t) -> occursCheck un t
91 u' <- fresh
88 u' <- fresh
92 u ~~ RCons name ty u'
89 u ~~ RCons name ty u'
93 unifyRows row r others u'
90 unifyRows row r others u'
94 unifyRows [] REmpty [] REmpty = return ()
91 unifyRows [] REmpty [] REmpty = return ()
95 unifyRows [] (RowVar v1) [] (RowVar v2) | v1 == v2 = return ()
92 unifyRows [] (RowVar v1) [] (RowVar v2) | v1 == v2 = return ()
96 unifyRows [] (RSkolem s1) [] (RSkolem s2) | s1 == s2 = return ()
93 unifyRows [] (RSkolem s1) [] (RSkolem s2) | s1 == s2 = return ()
97− unifyRows sd1 r1 sd2 r2 = throwError $ "Cannot unify " ++ prettyPrintRow (rowFromList (sd1, r1)) ++ " with " ++ prettyPrintRow (rowFromList (sd2, r2)) ++ "."
94+ 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
95 apply s (RUnknown u) = runSubstitution s u
99 apply s (RCons name ty r) = RCons name (apply s ty) (apply s r)
96 apply s (RCons name ty r) = RCons name (apply s ty) (apply s r)
100 apply _ r = r
97 apply _ r = r
@@ -136,11 +133,11 @@ unifyTypes t1 t2 = rethrow (\e -> "Error unifying type " ++ prettyPrintType t1 +
136 unifyTypes' (TypeConstructor c1) (TypeConstructor c2) = do
133 unifyTypes' (TypeConstructor c1) (TypeConstructor c2) = do
137 modulePath <- checkModulePath `fmap` get
134 modulePath <- checkModulePath `fmap` get
138 guardWith ("Cannot unify " ++ show c1 ++ " with " ++ show c2 ++ ".") (qualify modulePath c1 == qualify modulePath c2)
135 guardWith ("Cannot unify " ++ show c1 ++ " with " ++ show c2 ++ ".") (qualify modulePath c1 == qualify modulePath c2)
139− unifyTypes' (TypeApp t1 t2) (TypeApp t3 t4) = do
136+ unifyTypes' (TypeApp t3 t4) (TypeApp t5 t6) = do
140− t1 `unifyTypes` t3
137+ t3 `unifyTypes` t5
141− t2 `unifyTypes` t4
138+ t4 `unifyTypes` t6
142 unifyTypes' (Skolem s1) (Skolem s2) | s1 == s2 = return ()
139 unifyTypes' (Skolem s1) (Skolem s2) | s1 == s2 = return ()
143− unifyTypes' t1 t2 = throwError $ "Cannot unify " ++ prettyPrintType t1 ++ " with " ++ prettyPrintType t2 ++ "."
140+ unifyTypes' t3 t4 = throwError $ "Cannot unify " ++ prettyPrintType t3 ++ " with " ++ prettyPrintType t4 ++ "."
145isFunction :: Value -> Bool
142isFunction :: Value -> Bool
146isFunction (Abs _ _) = True
143isFunction (Abs _ _) = True
@@ -152,12 +149,12 @@ typeOf name val = do
152 (ty, sub, checks) <- runSubst $ case name of
149 (ty, sub, checks) <- runSubst $ case name of
153 Just ident | isFunction val ->
150 Just ident | isFunction val ->
154 case val of
151 case val of
155− TypedValue val ty -> do
152+ TypedValue value ty -> do
156 kind <- liftCheck $ kindOf ty
153 kind <- liftCheck $ kindOf ty
157 guardWith ("Expected type of kind *, was " ++ prettyPrintKind kind) $ kind == Star
154 guardWith ("Expected type of kind *, was " ++ prettyPrintKind kind) $ kind == Star
158 ty' <- replaceAllTypeSynonyms ty
155 ty' <- replaceAllTypeSynonyms ty
159 modulePath <- checkModulePath <$> get
156 modulePath <- checkModulePath <$> get
160− bindNames (M.singleton (modulePath, ident) (ty, LocalVariable)) $ check val ty'
157+ bindNames (M.singleton (modulePath, ident) (ty, LocalVariable)) $ check value ty'
161 return ty'
158 return ty'
163 me <- fresh
160 me <- fresh
@@ -175,7 +172,7 @@ escapeCheck checks ty sub =
176 visibleUnknowns = nub $ unknowns ty
173 visibleUnknowns = nub $ unknowns ty
178− forM_ checks $ \check -> case check of
175+ forM_ checks $ \c -> case c of
179 AnyUnifiable t -> do
176 AnyUnifiable t -> do
180 let unsolvedUnknowns = nub . unknowns $ apply sub t
177 let unsolvedUnknowns = nub . unknowns $ apply sub t
181 guardWith "Escape check fails" $ null $ unsolvedUnknowns \\ visibleUnknowns
178 guardWith "Escape check fails" $ null $ unsolvedUnknowns \\ visibleUnknowns
@@ -214,18 +211,18 @@ replaceAllTypeVars :: (D.Data d) => [(String, Type)] -> d -> d
214replaceAllTypeVars = foldl' (\f (name, ty) -> replaceTypeVars name ty . f) id
211replaceAllTypeVars = foldl' (\f (name, ty) -> replaceTypeVars name ty . f) id
216replaceTypeVars :: (D.Data d) => String -> Type -> d -> d
213replaceTypeVars :: (D.Data d) => String -> Type -> d -> d
217−replaceTypeVars name t = everywhereBut (mkQ False isShadowed) (mkT replace)
214+replaceTypeVars name t = everywhereBut (mkQ False isShadowed) (mkT replaceTypeVar)
219− replace (TypeVar v) | v == name = t
216+ replaceTypeVar (TypeVar v) | v == name = t
220− replace t = t
217+ replaceTypeVar other = other
221 isShadowed (ForAll v _) | v == name = True
218 isShadowed (ForAll v _) | v == name = True
222 isShadowed _ = False
219 isShadowed _ = False
224replaceRowVars :: (D.Data d) => String -> Row -> d -> d
221replaceRowVars :: (D.Data d) => String -> Row -> d -> d
225−replaceRowVars name r = everywhere (mkT replace)
222+replaceRowVars name r = everywhere (mkT replaceRowVar)
227− replace (RowVar v) | v == name = r
224+ replaceRowVar (RowVar v) | v == name = r
228− replace t = t
225+ replaceRowVar other = other
230replaceAllVarsWithUnknowns :: Type -> Subst Type
227replaceAllVarsWithUnknowns :: Type -> Subst Type
231replaceAllVarsWithUnknowns (ForAll ident ty) = replaceVarWithUnknown ident ty >>= replaceAllVarsWithUnknowns
228replaceAllVarsWithUnknowns (ForAll ident ty) = replaceVarWithUnknown ident ty >>= replaceAllVarsWithUnknowns
@@ -244,14 +241,10 @@ replaceAllTypeSynonyms d = do
244 either throwError return $ saturateAllTypeSynonyms syns d
241 either throwError return $ saturateAllTypeSynonyms syns d
246desaturateAllTypeSynonyms :: (D.Data d) => d -> d
243desaturateAllTypeSynonyms :: (D.Data d) => d -> d
247−desaturateAllTypeSynonyms = everywhere (mkT replace)
244+desaturateAllTypeSynonyms = everywhere (mkT replaceSaturatedTypeSynonym)
249− replace (SaturatedTypeSynonym name args) = foldl TypeApp (TypeConstructor name) args
246+ replaceSaturatedTypeSynonym (SaturatedTypeSynonym name args) = foldl TypeApp (TypeConstructor name) args
250− replace t = t
247+ replaceSaturatedTypeSynonym t = t
252−expandAllTypeSynonyms :: Type -> Subst Type
253−expandAllTypeSynonyms (SaturatedTypeSynonym name args) = expandTypeSynonym name args >>= expandAllTypeSynonyms
254−expandAllTypeSynonyms ty = return ty
256expandTypeSynonym :: Qualified ProperName -> [Type] -> Subst Type
249expandTypeSynonym :: Qualified ProperName -> [Type] -> Subst Type
257expandTypeSynonym name args = do
250expandTypeSynonym name args = do
@@ -276,9 +269,9 @@ infer' (StringLiteral _) = return String
276infer' (BooleanLiteral _) = return Boolean
269infer' (BooleanLiteral _) = return Boolean
277infer' (ArrayLiteral vals) = do
270infer' (ArrayLiteral vals) = do
278 ts <- mapM (infer) vals
271 ts <- mapM (infer) vals
279− arr <- fresh
272+ els <- fresh
280− forM_ ts $ \t -> arr ~~ Array t
273+ forM_ ts $ \t -> els ~~ Array t
281− return arr
274+ return els
282infer' (Unary op val) = do
275infer' (Unary op val) = do
283 t <- infer val
276 t <- infer val
284 inferUnary op t
277 inferUnary op t
@@ -324,7 +317,7 @@ infer' app@(App _ _) = do
324 ret <- fresh
317 ret <- fresh
325 checkFunctionApplications ft argss ret
318 checkFunctionApplications ft argss ret
326 return ret
319 return ret
327−infer' (Var var@(Qualified mp name)) = do
320+infer' (Var var) = do
328 ty <- lookupVariable var
321 ty <- lookupVariable var
329 replaceAllTypeSynonyms ty
322 replaceAllTypeSynonyms ty
330infer' (Block ss) = do
323infer' (Block ss) = do
@@ -355,6 +348,7 @@ infer' (TypedValue val ty) = do
355 ty' <- replaceAllTypeSynonyms ty
348 ty' <- replaceAllTypeSynonyms ty
356 check val ty'
349 check val ty'
357 return ty'
350 return ty'
351+infer' _ = error "Invalid argument to infer"
359inferProperty :: Type -> String -> Subst (Maybe Type)
353inferProperty :: Type -> String -> Subst (Maybe Type)
360inferProperty (Object row) prop = do
354inferProperty (Object row) prop = do
@@ -366,7 +360,7 @@ inferProperty (SaturatedTypeSynonym name args) prop = do
366inferProperty (ForAll ident ty) prop = do
360inferProperty (ForAll ident ty) prop = do
367 replaced <- replaceVarWithUnknown ident ty
361 replaced <- replaceVarWithUnknown ident ty
368 inferProperty replaced prop
362 inferProperty replaced prop
369−inferProperty _ prop = return Nothing
363+inferProperty _ _ = return Nothing
371inferUnary :: UnaryOperator -> Type -> Subst Type
365inferUnary :: UnaryOperator -> Type -> Subst Type
372inferUnary op val =
366inferUnary op val =
@@ -487,6 +481,7 @@ inferBinder val (ArrayBinder binders rest) = do
487inferBinder val (NamedBinder name binder) = do
481inferBinder val (NamedBinder name binder) = do
488 m <- inferBinder val binder
482 m <- inferBinder val binder
489 return $ M.insert name val m
483 return $ M.insert name val m
484+inferBinder _ _ = error "Invalid argument to inferBinder"
491inferGuardedBinder :: Type -> Binder -> Subst (M.Map Ident Type)
486inferGuardedBinder :: Type -> Binder -> Subst (M.Map Ident Type)
492inferGuardedBinder val (GuardedBinder cond binder) = do
487inferGuardedBinder val (GuardedBinder cond binder) = do
@@ -511,11 +506,11 @@ assignVariable name = do
511 _ -> return ()
506 _ -> return ()
513checkStatement :: M.Map Ident Type -> Type -> Statement -> Subst (Bool, M.Map Ident Type)
508checkStatement :: M.Map Ident Type -> Type -> Statement -> Subst (Bool, M.Map Ident Type)
514−checkStatement mass ret (VariableIntroduction name val) = do
509+checkStatement mass _ (VariableIntroduction name val) = do
515 assignVariable name
510 assignVariable name
516 t <- infer val
511 t <- infer val
517 return (False, M.insert name t mass)
512 return (False, M.insert name t mass)
518−checkStatement mass ret (Assignment ident val) = do
513+checkStatement mass _ (Assignment ident val) = do
519 t <- infer val
514 t <- infer val
520 case M.lookup ident mass of
515 case M.lookup ident mass of
521 Nothing -> throwError $ "No local variable with name " ++ show ident
516 Nothing -> throwError $ "No local variable with name " ++ show ident
@@ -567,7 +562,7 @@ checkBlock mass ret (s:ss) = do
567 bindLocalVariables (M.toList mass1) $ case (b1, ss) of
562 bindLocalVariables (M.toList mass1) $ case (b1, ss) of
568 (True, []) -> return (True, mass1)
563 (True, []) -> return (True, mass1)
569 (True, _) -> throwError "Unreachable code"
564 (True, _) -> throwError "Unreachable code"
570− (False, ss) -> checkBlock mass1 ret ss
565+ (False, ss') -> checkBlock mass1 ret ss'
572skolemize :: String -> Type -> Subst Type
567skolemize :: String -> Type -> Subst Type
573skolemize ident ty = do
568skolemize ident ty = do
@@ -609,7 +604,7 @@ check' app@(App _ _) ret = do
609 let (f, argss) = unfoldApplication app
604 let (f, argss) = unfoldApplication app
610 ft <- infer f
605 ft <- infer f
611 checkFunctionApplications ft argss ret
606 checkFunctionApplications ft argss ret
612−check' v@(Var var@(Qualified mp name)) ty = do
607+check' (Var var) ty = do
613 ty1 <- lookupVariable var
608 ty1 <- lookupVariable var
614 repl <- replaceAllTypeSynonyms ty1
609 repl <- replaceAllTypeSynonyms ty1
615 repl `subsumes` ty
610 repl `subsumes` ty
@@ -663,21 +658,21 @@ checkProperties ps row lax = let (ts, r') = rowToList row in go ps ts r' where
663 go [] ((p, _): _) _ | lax = return ()
658 go [] ((p, _): _) _ | lax = return ()
664 | otherwise = throwError $ prettyPrintValue (ObjectLiteral ps) ++ " does not have property " ++ p
659 | otherwise = throwError $ prettyPrintValue (ObjectLiteral ps) ++ " does not have property " ++ p
665 go ((p,_):_) [] REmpty = throwError $ "Property " ++ p ++ " is not present in closed object type " ++ prettyPrintRow row
660 go ((p,_):_) [] REmpty = throwError $ "Property " ++ p ++ " is not present in closed object type " ++ prettyPrintRow row
666− go ((p,v):ps) [] u@(RUnknown _) = do
661+ go ((p,v):ps') [] u@(RUnknown _) = do
667 ty <- infer v
662 ty <- infer v
668 rest <- fresh
663 rest <- fresh
669 u ~~ RCons p ty rest
664 u ~~ RCons p ty rest
670− go ps [] rest
665+ go ps' [] rest
671− go ((p,v):ps) ts r =
666+ go ((p,v):ps') ts r =
672 case lookup p ts of
667 case lookup p ts of
673 Nothing -> do
668 Nothing -> do
674 ty <- infer v
669 ty <- infer v
675 rest <- fresh
670 rest <- fresh
676 r ~~ RCons p ty rest
671 r ~~ RCons p ty rest
677− go ps ts rest
672+ go ps' ts rest
678 Just ty -> do
673 Just ty -> do
679 check v ty
674 check v ty
680− go ps (delete (p, ty) ts) r
675+ go ps' (delete (p, ty) ts) r
681 go _ _ _ = throwError $ prettyPrintValue (ObjectLiteral ps) ++ " does not have type " ++ prettyPrintType (Object row)
676 go _ _ _ = throwError $ prettyPrintValue (ObjectLiteral ps) ++ " does not have type " ++ prettyPrintType (Object row)
683unfoldApplication :: Value -> (Value, [[Value]])
678unfoldApplication :: Value -> (Value, [[Value]])