@@ -14,6 +14,7 @@
14-----------------------------------------------------------------------------
14-----------------------------------------------------------------------------
16{-# LANGUAGE FlexibleContexts #-}
16{-# LANGUAGE FlexibleContexts #-}
17+{-# LANGUAGE ScopedTypeVariables #-}
17{-# LANGUAGE MultiParamTypeClasses #-}
18{-# LANGUAGE MultiParamTypeClasses #-}
18{-# LANGUAGE OverloadedStrings #-}
19{-# LANGUAGE OverloadedStrings #-}
@@ -46,10 +47,9 @@ import Data.Maybe (fromMaybe)
46import qualified Data.Map as M
47import qualified Data.Map as M
48import Control.Monad
49import Control.Monad
49−import Control.Monad.State
50+import Control.Monad.State.Class (MonadState(..), gets)
50−import Control.Monad.Unify
51import Control.Monad.Error.Class (MonadError(..))
51import Control.Monad.Error.Class (MonadError(..))
52−import Control.Monad.Writer.Class (tell)
52+import Control.Monad.Writer.Class (MonadWriter(..))
54import Language.PureScript.Crash
54import Language.PureScript.Crash
55import Language.PureScript.AST
55import Language.PureScript.AST
@@ -69,11 +69,13 @@ import Language.PureScript.TypeChecker.Unify
69import Language.PureScript.TypeClassDictionaries
69import Language.PureScript.TypeClassDictionaries
70import Language.PureScript.Types
70import Language.PureScript.Types
73−-- Infer the types of multiple mutually-recursive values, and return elaborated values including
72+-- | Infer the types of multiple mutually-recursive values, and return elaborated values including
74-- type class dictionaries and type annotations.
73-- type class dictionaries and type annotations.
75+ (Functor m, Applicative m, MonadState CheckState m, MonadError MultipleErrors m, MonadWriter MultipleErrors m) =>
76−typesOf :: ModuleName -> [(Ident, Expr)] -> Check [(Ident, (Expr, Type))]
78+ m [(Ident, (Expr, Type))]
77typesOf moduleName vals = do
79typesOf moduleName vals = do
78 tys <- fmap tidyUp . liftUnifyWarnings replace $ do
80 tys <- fmap tidyUp . liftUnifyWarnings replace $ do
79 (untyped, typed, dict, untypedDict) <- typeDictionaryForBindingGroup moduleName vals
81 (untyped, typed, dict, untypedDict) <- typeDictionaryForBindingGroup moduleName vals
@@ -91,17 +93,21 @@ typesOf moduleName vals = do
91 return (ident, (val', varIfUnknown ty))
93 return (ident, (val', varIfUnknown ty))
93 -- Apply the substitution that was returned from runUnify to both types and (type-annotated) values
95 -- Apply the substitution that was returned from runUnify to both types and (type-annotated) values
94− tidyUp (ts, sub) = map (\(i, (val, ty)) -> (i, (overTypes (sub $?) val, sub $? ty))) ts
96+ tidyUp (ts, sub) = map (\(i, (val, ty)) -> (i, (overTypes (substituteType sub) val, substituteType sub ty))) ts
95 -- Replace all the wildcards types with their inferred types
97 -- Replace all the wildcards types with their inferred types
96− replace sub (ErrorMessage hints (WildcardInferredType ty)) = ErrorMessage hints $ WildcardInferredType (sub $? ty)
98+ replace sub (ErrorMessage hints (WildcardInferredType ty)) = ErrorMessage hints . WildcardInferredType $ substituteType sub ty
97− replace sub (ErrorMessage hints (MissingTypeDeclaration name ty)) = ErrorMessage hints $ MissingTypeDeclaration name (varIfUnknown (sub $? ty))
99+ replace sub (ErrorMessage hints (MissingTypeDeclaration name ty)) = ErrorMessage hints $ MissingTypeDeclaration name (varIfUnknown (substituteType sub ty))
98 replace _ em = em
100 replace _ em = em
100type TypeData = M.Map (ModuleName, Ident) (Type, NameKind, NameVisibility)
102type TypeData = M.Map (ModuleName, Ident) (Type, NameKind, NameVisibility)
102type UntypedData = [(Ident, Type)]
104type UntypedData = [(Ident, Type)]
106+typeDictionaryForBindingGroup ::
107+ (Functor m, Applicative m, MonadState CheckState m, MonadError MultipleErrors m, MonadWriter MultipleErrors m) =>
104−typeDictionaryForBindingGroup :: ModuleName -> [(Ident, Expr)] -> UnifyT Type Check ([(Ident, Expr)], [(Ident, (Expr, Type, Bool))], TypeData, UntypedData)
110+ m ([(Ident, Expr)], [(Ident, (Expr, Type, Bool))], TypeData, UntypedData)
105typeDictionaryForBindingGroup moduleName vals = do
111typeDictionaryForBindingGroup moduleName vals = do
107 -- Map each declaration to a name/value pair, with an optional type, if the declaration is typed
113 -- Map each declaration to a name/value pair, with an optional type, if the declaration is typed
@@ -113,7 +119,7 @@ typeDictionaryForBindingGroup moduleName vals = do
113 typedDict = map (\(ident, (_, ty, _)) -> (ident, ty)) typed
119 typedDict = map (\(ident, (_, ty, _)) -> (ident, ty)) typed
115 -- Create fresh unification variables for the types of untyped declarations
121 -- Create fresh unification variables for the types of untyped declarations
116− untypedNames <- replicateM (length untyped) fresh
122+ untypedNames <- replicateM (length untyped) freshType
119 -- Make a map of names to the unification variables of untyped declarations
125 -- Make a map of names to the unification variables of untyped declarations
@@ -122,12 +128,17 @@ typeDictionaryForBindingGroup moduleName vals = do
122 dict = M.fromList (map (\(ident, ty) -> ((moduleName, ident), (ty, Private, Undefined))) $ typedDict ++ untypedDict)
128 dict = M.fromList (map (\(ident, ty) -> ((moduleName, ident), (ty, Private, Undefined))) $ typedDict ++ untypedDict)
123 return (untyped, typed, dict, untypedDict)
129 return (untyped, typed, dict, untypedDict)
125−checkTypedBindingGroupElement :: ModuleName -> (Ident, (Expr, Type, Bool)) -> TypeData -> UnifyT Type Check (Ident, (Expr, Type))
131+checkTypedBindingGroupElement ::
132+ (Functor m, Applicative m, MonadState CheckState m, MonadError MultipleErrors m, MonadWriter MultipleErrors m) =>
134+ (Ident, (Expr, Type, Bool)) ->
136+ m (Ident, (Expr, Type))
126checkTypedBindingGroupElement mn (ident, (val', ty, checkType)) dict = do
137checkTypedBindingGroupElement mn (ident, (val', ty, checkType)) dict = do
127 -- Replace type wildcards
138 -- Replace type wildcards
128 ty' <- replaceTypeWildcards ty
139 ty' <- replaceTypeWildcards ty
129 -- Kind check
140 -- Kind check
130− (kind, args) <- liftCheck $ kindOfWithScopedVars ty
141+ (kind, args) <- kindOfWithScopedVars ty
131 checkTypeKind ty kind
142 checkTypeKind ty kind
132 -- Check the type with the new names in scope
143 -- Check the type with the new names in scope
133 ty'' <- introduceSkolemScope <=< replaceAllTypeSynonyms <=< replaceTypeWildcards $ ty'
144 ty'' <- introduceSkolemScope <=< replaceAllTypeSynonyms <=< replaceTypeWildcards $ ty'
@@ -136,17 +147,21 @@ checkTypedBindingGroupElement mn (ident, (val', ty, checkType)) dict = do
136 else return (TypedValue False val' ty'')
147 else return (TypedValue False val' ty'')
137 return (ident, (val'', ty''))
148 return (ident, (val'', ty''))
139−typeForBindingGroupElement :: Bool -> (Ident, Expr) -> TypeData -> UntypedData -> UnifyT Type Check (Ident, (Expr, Type))
150+typeForBindingGroupElement ::
151+ (Functor m, Applicative m, MonadState CheckState m, MonadError MultipleErrors m, MonadWriter MultipleErrors m) =>
156+ m (Ident, (Expr, Type))
140typeForBindingGroupElement warn (ident, val) dict untypedDict = do
157typeForBindingGroupElement warn (ident, val) dict untypedDict = do
141 -- Infer the type with the new names in scope
158 -- Infer the type with the new names in scope
142 TypedValue _ val' ty <- bindNames dict $ infer val
159 TypedValue _ val' ty <- bindNames dict $ infer val
143− ty =?= fromMaybe (internalError "name not found in dictionary") (lookup ident untypedDict)
160+ unifyTypes ty $ fromMaybe (internalError "name not found in dictionary") (lookup ident untypedDict)
144 when warn . tell . errorMessage $ MissingTypeDeclaration ident ty
161 when warn . tell . errorMessage $ MissingTypeDeclaration ident ty
145 return (ident, (TypedValue True val' ty, ty))
162 return (ident, (TypedValue True val' ty, ty))
148−-- Check if a value contains a type annotation
164+-- | Check if a value contains a type annotation
150isTyped :: (Ident, Expr) -> Either (Ident, Expr) (Ident, (Expr, Type, Bool))
165isTyped :: (Ident, Expr) -> Either (Ident, Expr) (Ident, (Expr, Type, Bool))
151isTyped (name, TypedValue checkType value ty) = Right (name, (value, ty, checkType))
166isTyped (name, TypedValue checkType value ty) = Right (name, (value, ty, checkType))
152isTyped (name, value) = Left (name, value)
167isTyped (name, value) = Left (name, value)
@@ -162,10 +177,12 @@ overTypes f = let (_, f', _) = everywhereOnValues id g id in f'
162 g (TypeClassDictionary (nm, tys) sco) = TypeClassDictionary (nm, map f tys) sco
177 g (TypeClassDictionary (nm, tys) sco) = TypeClassDictionary (nm, map f tys) sco
163 g other = other
178 g other = other
166−-- Replace type class dictionary placeholders with inferred type class dictionaries
180+-- | Replace type class dictionary placeholders with inferred type class dictionaries
168−replaceTypeClassDictionaries :: ModuleName -> Expr -> Check Expr
181+replaceTypeClassDictionaries ::
182+ (Functor m, Applicative m, MonadState CheckState m, MonadError MultipleErrors m, MonadWriter MultipleErrors m) =>
169replaceTypeClassDictionaries mn =
186replaceTypeClassDictionaries mn =
170 let (_, f, _) = everywhereOnValuesTopDownM return go return
187 let (_, f, _) = everywhereOnValuesTopDownM return go return
@@ -173,20 +190,24 @@ replaceTypeClassDictionaries mn =
173 go (TypeClassDictionary constraint dicts) = entails mn dicts constraint
190 go (TypeClassDictionary constraint dicts) = entails mn dicts constraint
174 go other = return other
191 go other = return other
177−-- Check the kind of a type, failing if it is not of kind *.
193+-- | Check the kind of a type, failing if it is not of kind *.
179−checkTypeKind :: Type -> Kind -> UnifyT t Check ()
194+checkTypeKind ::
195+ (Functor m, Applicative m, MonadState CheckState m, MonadError MultipleErrors m) =>
180checkTypeKind ty kind = guardWith (errorMessage (ExpectedType ty kind)) $ kind == Star
199checkTypeKind ty kind = guardWith (errorMessage (ExpectedType ty kind)) $ kind == Star
183−-- Remove any ForAlls and ConstrainedType constructors in a type by introducing new unknowns
201+-- | Remove any ForAlls and ConstrainedType constructors in a type by introducing new unknowns
184-- or TypeClassDictionary values.
202-- or TypeClassDictionary values.
186-- This is necessary during type checking to avoid unifying a polymorphic type with a
204-- This is necessary during type checking to avoid unifying a polymorphic type with a
187-- unification variable.
205-- unification variable.
189−instantiatePolyTypeWithUnknowns :: Expr -> Type -> UnifyT Type Check (Expr, Type)
206+instantiatePolyTypeWithUnknowns ::
207+ (Functor m, Applicative m, MonadState CheckState m, MonadError MultipleErrors m) =>
190instantiatePolyTypeWithUnknowns val (ForAll ident ty _) = do
211instantiatePolyTypeWithUnknowns val (ForAll ident ty _) = do
191 ty' <- replaceVarWithUnknown ident ty
212 ty' <- replaceVarWithUnknown ident ty
192 instantiatePolyTypeWithUnknowns val ty'
213 instantiatePolyTypeWithUnknowns val ty'
@@ -196,16 +217,18 @@ instantiatePolyTypeWithUnknowns val (ConstrainedType constraints ty) = do
196 return (foldl App val (map (flip TypeClassDictionary dicts) constraints), ty')
217 return (foldl App val (map (flip TypeClassDictionary dicts) constraints), ty')
197instantiatePolyTypeWithUnknowns val ty = return (val, ty)
218instantiatePolyTypeWithUnknowns val ty = return (val, ty)
200−-- Infer a type for a value, rethrowing any error to provide a more useful error message
220+-- | Infer a type for a value, rethrowing any error to provide a more useful error message
202−infer :: Expr -> UnifyT Type Check Expr
222+ (Functor m, Applicative m, MonadState CheckState m, MonadError MultipleErrors m, MonadWriter MultipleErrors m) =>
203infer val = rethrow (addHint (ErrorInferringType val)) $ infer' val
225infer val = rethrow (addHint (ErrorInferringType val)) $ infer' val
206−-- Infer a type for a value
227+-- | Infer a type for a value
208−infer' :: Expr -> UnifyT Type Check Expr
229+ (Functor m, Applicative m, MonadState CheckState m, MonadError MultipleErrors m, MonadWriter MultipleErrors m) =>
209infer' v@(NumericLiteral (Left _)) = return $ TypedValue True v tyInt
232infer' v@(NumericLiteral (Left _)) = return $ TypedValue True v tyInt
210infer' v@(NumericLiteral (Right _)) = return $ TypedValue True v tyNumber
233infer' v@(NumericLiteral (Right _)) = return $ TypedValue True v tyNumber
211infer' v@(StringLiteral _) = return $ TypedValue True v tyString
234infer' v@(StringLiteral _) = return $ TypedValue True v tyString
@@ -213,8 +236,8 @@ infer' v@(CharLiteral _) = return $ TypedValue True v tyChar
213infer' v@(BooleanLiteral _) = return $ TypedValue True v tyBoolean
236infer' v@(BooleanLiteral _) = return $ TypedValue True v tyBoolean
214infer' (ArrayLiteral vals) = do
237infer' (ArrayLiteral vals) = do
215 ts <- traverse infer vals
238 ts <- traverse infer vals
216− els <- fresh
239+ els <- freshType
217− forM_ ts $ \(TypedValue _ _ t) -> els =?= t
240+ forM_ ts $ \(TypedValue _ _ t) -> unifyTypes els t
218 return $ TypedValue True (ArrayLiteral ts) (TypeApp tyArray els)
241 return $ TypedValue True (ArrayLiteral ts) (TypeApp tyArray els)
219infer' (ObjectLiteral ps) = do
242infer' (ObjectLiteral ps) = do
220 ensureNoDuplicateProperties ps
243 ensureNoDuplicateProperties ps
@@ -224,20 +247,20 @@ infer' (ObjectLiteral ps) = do
224 return $ TypedValue True (ObjectLiteral (zip (map fst ps) ts)) ty
247 return $ TypedValue True (ObjectLiteral (zip (map fst ps) ts)) ty
225infer' (ObjectUpdate o ps) = do
248infer' (ObjectUpdate o ps) = do
226 ensureNoDuplicateProperties ps
249 ensureNoDuplicateProperties ps
227− row <- fresh
250+ row <- freshType
228 newVals <- zipWith (\(name, _) t -> (name, t)) ps <$> traverse (infer . snd) ps
251 newVals <- zipWith (\(name, _) t -> (name, t)) ps <$> traverse (infer . snd) ps
229 let newTys = map (\(name, TypedValue _ _ ty) -> (name, ty)) newVals
252 let newTys = map (\(name, TypedValue _ _ ty) -> (name, ty)) newVals
230− oldTys <- zip (map fst ps) <$> replicateM (length ps) fresh
253+ oldTys <- zip (map fst ps) <$> replicateM (length ps) freshType
231 let oldTy = TypeApp tyObject $ rowFromList (oldTys, row)
254 let oldTy = TypeApp tyObject $ rowFromList (oldTys, row)
232 o' <- TypedValue True <$> check o oldTy <*> pure oldTy
255 o' <- TypedValue True <$> check o oldTy <*> pure oldTy
233 return $ TypedValue True (ObjectUpdate o' newVals) $ TypeApp tyObject $ rowFromList (newTys, row)
256 return $ TypedValue True (ObjectUpdate o' newVals) $ TypeApp tyObject $ rowFromList (newTys, row)
234infer' (Accessor prop val) = rethrow (addHint (ErrorCheckingAccessor val prop)) $ do
257infer' (Accessor prop val) = rethrow (addHint (ErrorCheckingAccessor val prop)) $ do
235− field <- fresh
258+ field <- freshType
236− rest <- fresh
259+ rest <- freshType
237 typed <- check val (TypeApp tyObject (RCons prop field rest))
260 typed <- check val (TypeApp tyObject (RCons prop field rest))
238 return $ TypedValue True (Accessor prop typed) field
261 return $ TypedValue True (Accessor prop typed) field
239infer' (Abs (Left arg) ret) = do
262infer' (Abs (Left arg) ret) = do
240− ty <- fresh
263+ ty <- freshType
241 Just moduleName <- checkCurrentModule <$> get
264 Just moduleName <- checkCurrentModule <$> get
242 withBindingGroupVisible $ bindLocalVariables moduleName [(arg, ty, Defined)] $ do
265 withBindingGroupVisible $ bindLocalVariables moduleName [(arg, ty, Defined)] $ do
243 body@(TypedValue _ _ bodyTy) <- infer' ret
266 body@(TypedValue _ _ bodyTy) <- infer' ret
@@ -264,7 +287,7 @@ infer' v@(Constructor c) = do
264 return $ TypedValue True v' ty'
287 return $ TypedValue True v' ty'
265infer' (Case vals binders) = do
288infer' (Case vals binders) = do
266 (vals', ts) <- instantiateForBinders vals binders
289 (vals', ts) <- instantiateForBinders vals binders
267− ret <- fresh
290+ ret <- freshType
268 binders' <- checkBinders ts ret binders
291 binders' <- checkBinders ts ret binders
269 return $ TypedValue True (Case vals' binders') ret
292 return $ TypedValue True (Case vals' binders') ret
270infer' (IfThenElse cond th el) = do
293infer' (IfThenElse cond th el) = do
@@ -281,7 +304,7 @@ infer' (SuperClassDictionary className tys) = do
281 return $ TypeClassDictionary (className, tys) dicts
304 return $ TypeClassDictionary (className, tys) dicts
282infer' (TypedValue checkType val ty) = do
305infer' (TypedValue checkType val ty) = do
283 Just moduleName <- checkCurrentModule <$> get
306 Just moduleName <- checkCurrentModule <$> get
284− (kind, args) <- liftCheck $ kindOfWithScopedVars ty
307+ (kind, args) <- kindOfWithScopedVars ty
285 checkTypeKind ty kind
308 checkTypeKind ty kind
286 ty' <- introduceSkolemScope <=< replaceAllTypeSynonyms <=< replaceTypeWildcards $ ty
309 ty' <- introduceSkolemScope <=< replaceAllTypeSynonyms <=< replaceTypeWildcards $ ty
287 val' <- if checkType then withScopedTypeVars moduleName args (check val ty') else return val
310 val' <- if checkType then withScopedTypeVars moduleName args (check val ty') else return val
@@ -289,22 +312,28 @@ infer' (TypedValue checkType val ty) = do
289infer' (PositionedValue pos _ val) = warnAndRethrowWithPosition pos $ infer' val
312infer' (PositionedValue pos _ val) = warnAndRethrowWithPosition pos $ infer' val
290infer' _ = internalError "Invalid argument to infer"
313infer' _ = internalError "Invalid argument to infer"
292−inferLetBinding :: [Declaration] -> [Declaration] -> Expr -> (Expr -> UnifyT Type Check Expr) -> UnifyT Type Check ([Declaration], Expr)
315+inferLetBinding ::
316+ (Functor m, Applicative m, MonadState CheckState m, MonadError MultipleErrors m, MonadWriter MultipleErrors m) =>
321+ m ([Declaration], Expr)
293inferLetBinding seen [] ret j = (,) seen <$> withBindingGroupVisible (j ret)
322inferLetBinding seen [] ret j = (,) seen <$> withBindingGroupVisible (j ret)
294inferLetBinding seen (ValueDeclaration ident nameKind [] (Right (tv@(TypedValue checkType val ty))) : rest) ret j = do
323inferLetBinding seen (ValueDeclaration ident nameKind [] (Right (tv@(TypedValue checkType val ty))) : rest) ret j = do
295 Just moduleName <- checkCurrentModule <$> get
324 Just moduleName <- checkCurrentModule <$> get
296− (kind, args) <- liftCheck $ kindOfWithScopedVars ty
325+ (kind, args) <- kindOfWithScopedVars ty
297 checkTypeKind ty kind
326 checkTypeKind ty kind
298 let dict = M.singleton (moduleName, ident) (ty, nameKind, Undefined)
327 let dict = M.singleton (moduleName, ident) (ty, nameKind, Undefined)
299 ty' <- introduceSkolemScope <=< replaceAllTypeSynonyms <=< replaceTypeWildcards $ ty
328 ty' <- introduceSkolemScope <=< replaceAllTypeSynonyms <=< replaceTypeWildcards $ ty
300 TypedValue _ val' ty'' <- if checkType then withScopedTypeVars moduleName args (bindNames dict (check val ty')) else return tv
329 TypedValue _ val' ty'' <- if checkType then withScopedTypeVars moduleName args (bindNames dict (check val ty')) else return tv
301 bindNames (M.singleton (moduleName, ident) (ty'', nameKind, Defined)) $ inferLetBinding (seen ++ [ValueDeclaration ident nameKind [] (Right (TypedValue checkType val' ty''))]) rest ret j
330 bindNames (M.singleton (moduleName, ident) (ty'', nameKind, Defined)) $ inferLetBinding (seen ++ [ValueDeclaration ident nameKind [] (Right (TypedValue checkType val' ty''))]) rest ret j
302inferLetBinding seen (ValueDeclaration ident nameKind [] (Right val) : rest) ret j = do
331inferLetBinding seen (ValueDeclaration ident nameKind [] (Right val) : rest) ret j = do
303− valTy <- fresh
332+ valTy <- freshType
304 Just moduleName <- checkCurrentModule <$> get
333 Just moduleName <- checkCurrentModule <$> get
305 let dict = M.singleton (moduleName, ident) (valTy, nameKind, Undefined)
334 let dict = M.singleton (moduleName, ident) (valTy, nameKind, Undefined)
306 TypedValue _ val' valTy' <- bindNames dict $ infer val
335 TypedValue _ val' valTy' <- bindNames dict $ infer val
307− valTy =?= valTy'
336+ unifyTypes valTy valTy'
308 bindNames (M.singleton (moduleName, ident) (valTy', nameKind, Defined)) $ inferLetBinding (seen ++ [ValueDeclaration ident nameKind [] (Right val')]) rest ret j
337 bindNames (M.singleton (moduleName, ident) (valTy', nameKind, Defined)) $ inferLetBinding (seen ++ [ValueDeclaration ident nameKind [] (Right val')]) rest ret j
309inferLetBinding seen (BindingGroupDeclaration ds : rest) ret j = do
338inferLetBinding seen (BindingGroupDeclaration ds : rest) ret j = do
310 Just moduleName <- checkCurrentModule <$> get
339 Just moduleName <- checkCurrentModule <$> get
@@ -320,16 +349,18 @@ inferLetBinding seen (PositionedDeclaration pos com d : ds) ret j = warnAndRethr
320 return (PositionedDeclaration pos com d' : ds', val')
349 return (PositionedDeclaration pos com d' : ds', val')
321inferLetBinding _ _ _ _ = internalError "Invalid argument to inferLetBinding"
350inferLetBinding _ _ _ _ = internalError "Invalid argument to inferLetBinding"
324−-- Infer the types of variables brought into scope by a binder
352+-- | Infer the types of variables brought into scope by a binder
325−--
353+inferBinder :: forall m.
354+ (Functor m, Applicative m, MonadState CheckState m, MonadError MultipleErrors m, MonadWriter MultipleErrors m) =>
326−inferBinder :: Type -> Binder -> UnifyT Type Check (M.Map Ident Type)
357+ m (M.Map Ident Type)
327inferBinder _ NullBinder = return M.empty
358inferBinder _ NullBinder = return M.empty
328−inferBinder val (StringBinder _) = val =?= tyString >> return M.empty
359+inferBinder val (StringBinder _) = unifyTypes val tyString >> return M.empty
329−inferBinder val (CharBinder _) = val =?= tyChar >> return M.empty
360+inferBinder val (CharBinder _) = unifyTypes val tyChar >> return M.empty
330−inferBinder val (NumberBinder (Left _)) = val =?= tyInt >> return M.empty
361+inferBinder val (NumberBinder (Left _)) = unifyTypes val tyInt >> return M.empty
331−inferBinder val (NumberBinder (Right _)) = val =?= tyNumber >> return M.empty
362+inferBinder val (NumberBinder (Right _)) = unifyTypes val tyNumber >> return M.empty
332−inferBinder val (BooleanBinder _) = val =?= tyBoolean >> return M.empty
363+inferBinder val (BooleanBinder _) = unifyTypes val tyBoolean >> return M.empty
333inferBinder val (VarBinder name) = return $ M.singleton name val
364inferBinder val (VarBinder name) = return $ M.singleton name val
334inferBinder val (ConstructorBinder ctor binders) = do
365inferBinder val (ConstructorBinder ctor binders) = do
335 env <- getEnv
366 env <- getEnv
@@ -339,7 +370,7 @@ inferBinder val (ConstructorBinder ctor binders) = do
339 fn' <- introduceSkolemScope <=< replaceAllTypeSynonyms $ fn
370 fn' <- introduceSkolemScope <=< replaceAllTypeSynonyms $ fn
340 let (args, ret) = peelArgs fn'
371 let (args, ret) = peelArgs fn'
341 unless (length args == length binders) . throwError . errorMessage $ IncorrectConstructorArity ctor
372 unless (length args == length binders) . throwError . errorMessage $ IncorrectConstructorArity ctor
342− ret =?= val
373+ unifyTypes ret val
343 M.unions <$> zipWithM inferBinder (reverse args) binders
374 M.unions <$> zipWithM inferBinder (reverse args) binders
344 _ -> throwError . errorMessage $ UnknownDataConstructor ctor Nothing
375 _ -> throwError . errorMessage $ UnknownDataConstructor ctor Nothing
@@ -349,23 +380,23 @@ inferBinder val (ConstructorBinder ctor binders) = do
349 go args (TypeApp (TypeApp fn arg) ret) | fn == tyFunction = go (arg : args) ret
380 go args (TypeApp (TypeApp fn arg) ret) | fn == tyFunction = go (arg : args) ret
350 go args ret = (args, ret)
381 go args ret = (args, ret)
351inferBinder val (ObjectBinder props) = do
382inferBinder val (ObjectBinder props) = do
352− row <- fresh
383+ row <- freshType
353− rest <- fresh
384+ rest <- freshType
354 m1 <- inferRowProperties row rest props
385 m1 <- inferRowProperties row rest props
355− val =?= TypeApp tyObject row
386+ unifyTypes val (TypeApp tyObject row)
356 return m1
387 return m1
358− inferRowProperties :: Type -> Type -> [(String, Binder)] -> UnifyT Type Check (M.Map Ident Type)
389+ inferRowProperties :: Type -> Type -> [(String, Binder)] -> m (M.Map Ident Type)
359− inferRowProperties nrow row [] = nrow =?= row >> return M.empty
390+ inferRowProperties nrow row [] = unifyTypes nrow row >> return M.empty
360 inferRowProperties nrow row ((name, binder):binders) = do
391 inferRowProperties nrow row ((name, binder):binders) = do
361− propTy <- fresh
392+ propTy <- freshType
362 m1 <- inferBinder propTy binder
393 m1 <- inferBinder propTy binder
363 m2 <- inferRowProperties nrow (RCons name propTy row) binders
394 m2 <- inferRowProperties nrow (RCons name propTy row) binders
364 return $ m1 `M.union` m2
395 return $ m1 `M.union` m2
365inferBinder val (ArrayBinder binders) = do
396inferBinder val (ArrayBinder binders) = do
366− el <- fresh
397+ el <- freshType
367 m1 <- M.unions <$> traverse (inferBinder el) binders
398 m1 <- M.unions <$> traverse (inferBinder el) binders
368− val =?= TypeApp tyArray el
399+ unifyTypes val (TypeApp tyArray el)
369 return m1
400 return m1
370inferBinder val (NamedBinder name binder) = do
401inferBinder val (NamedBinder name binder) = do
371 m <- inferBinder val binder
402 m <- inferBinder val binder
@@ -377,9 +408,9 @@ inferBinder val (PositionedBinder pos _ binder) =
377-- and use `kindOfWithScopedVars`.
408-- and use `kindOfWithScopedVars`.
378inferBinder val (TypedBinder ty binder) = do
409inferBinder val (TypedBinder ty binder) = do
379 ty1 <- replaceAllTypeSynonyms <=< replaceTypeWildcards $ ty
410 ty1 <- replaceAllTypeSynonyms <=< replaceTypeWildcards $ ty
380− kind <- liftCheck $ kindOf ty1
411+ kind <- kindOf ty1
381 checkTypeKind ty1 kind
412 checkTypeKind ty1 kind
382− val =?= ty1
413+ unifyTypes val ty1
383 inferBinder val binder
414 inferBinder val binder
385-- | Returns true if a binder requires its argument type to be a monotype.
416-- | Returns true if a binder requires its argument type to be a monotype.
@@ -392,7 +423,11 @@ binderRequiresMonotype (PositionedBinder _ _ b) = binderRequiresMonotype b
392binderRequiresMonotype _ = True
423binderRequiresMonotype _ = True
394-- | Instantiate polytypes only when necessitated by a binder.
425-- | Instantiate polytypes only when necessitated by a binder.
395−instantiateForBinders :: [Expr] -> [CaseAlternative] -> UnifyT Type Check ([Expr], [Type])
426+instantiateForBinders ::
427+ (Functor m, Applicative m, MonadState CheckState m, MonadError MultipleErrors m, MonadWriter MultipleErrors m) =>
429+ [CaseAlternative] ->
396instantiateForBinders vals cas = unzip <$> zipWithM (\val inst -> do
431instantiateForBinders vals cas = unzip <$> zipWithM (\val inst -> do
397 TypedValue _ val' ty <- infer val
432 TypedValue _ val' ty <- infer val
@@ -405,7 +440,12 @@ instantiateForBinders vals cas = unzip <$> zipWithM (\val inst -> do
406-- Check the types of the return values in a set of binders in a case statement
441-- Check the types of the return values in a set of binders in a case statement
408−checkBinders :: [Type] -> Type -> [CaseAlternative] -> UnifyT Type Check [CaseAlternative]
443+checkBinders ::
444+ (Functor m, Applicative m, MonadState CheckState m, MonadError MultipleErrors m, MonadWriter MultipleErrors m) =>
447+ [CaseAlternative] ->
409checkBinders _ _ [] = return []
449checkBinders _ _ [] = return []
410checkBinders nvals ret (CaseAlternative binders result : bs) = do
450checkBinders nvals ret (CaseAlternative binders result : bs) = do
411 guardWith (errorMessage $ OverlappingArgNames Nothing) $
451 guardWith (errorMessage $ OverlappingArgNames Nothing) $
@@ -430,13 +470,21 @@ checkBinders nvals ret (CaseAlternative binders result : bs) = do
431-- Check the type of a value, rethrowing errors to provide a better error message
471-- Check the type of a value, rethrowing errors to provide a better error message
433−check :: Expr -> Type -> UnifyT Type Check Expr
473+check ::
474+ (Functor m, Applicative m, MonadState CheckState m, MonadError MultipleErrors m, MonadWriter MultipleErrors m) =>
434check val ty = rethrow (addHint (ErrorCheckingType val ty)) $ check' val ty
478check val ty = rethrow (addHint (ErrorCheckingType val ty)) $ check' val ty
437-- Check the type of a value
481-- Check the type of a value
439−check' :: Expr -> Type -> UnifyT Type Check Expr
483+check' :: forall m.
484+ (Functor m, Applicative m, MonadState CheckState m, MonadError MultipleErrors m, MonadWriter MultipleErrors m) =>
440check' val (ForAll ident ty _) = do
488check' val (ForAll ident ty _) = do
441 scope <- newSkolemScope
489 scope <- newSkolemScope
442 sko <- newSkolemConstant
490 sko <- newSkolemConstant
@@ -446,15 +494,15 @@ check' val (ForAll ident ty _) = do
446 return $ TypedValue True val' (ForAll ident ty (Just scope))
494 return $ TypedValue True val' (ForAll ident ty (Just scope))
447check' val t@(ConstrainedType constraints ty) = do
495check' val t@(ConstrainedType constraints ty) = do
448 dictNames <- forM constraints $ \(Qualified _ (ProperName className), _) -> do
496 dictNames <- forM constraints $ \(Qualified _ (ProperName className), _) -> do
449− n <- liftCheck freshDictionaryName
497+ n <- freshDictionaryName
450 return $ Ident $ "__dict_" ++ className ++ "_" ++ show n
498 return $ Ident $ "__dict_" ++ className ++ "_" ++ show n
451− dicts <- join <$> liftCheck (zipWithM (newDictionaries []) (map (Qualified Nothing) dictNames) constraints)
499+ dicts <- join <$> zipWithM (newDictionaries []) (map (Qualified Nothing) dictNames) constraints
452 val' <- withBindingGroupVisible $ withTypeClassDictionaries dicts $ check val ty
500 val' <- withBindingGroupVisible $ withTypeClassDictionaries dicts $ check val ty
453 return $ TypedValue True (foldr (Abs . Left) val' dictNames) t
501 return $ TypedValue True (foldr (Abs . Left) val' dictNames) t
455 -- | Add a dictionary for the constraint to the scope, and dictionaries
503 -- | Add a dictionary for the constraint to the scope, and dictionaries
456− -- for all implies superclass instances.
504+ -- for all implied superclass instances.
457− newDictionaries :: [(Qualified ProperName, Integer)] -> Qualified Ident -> (Qualified ProperName, [Type]) -> Check [TypeClassDictionaryInScope]
505+ newDictionaries :: [(Qualified ProperName, Integer)] -> Qualified Ident -> (Qualified ProperName, [Type]) -> m [TypeClassDictionaryInScope]
458 newDictionaries path name (className, instanceTy) = do
506 newDictionaries path name (className, instanceTy) = do
459 tcs <- gets (typeClasses . checkEnv)
507 tcs <- gets (typeClasses . checkEnv)
460 let (args, _, superclasses) = fromMaybe (internalError "newDictionaries: type class lookup failed") $ M.lookup className tcs
508 let (args, _, superclasses) = fromMaybe (internalError "newDictionaries: type class lookup failed") $ M.lookup className tcs
@@ -471,7 +519,7 @@ check' val u@(TUnknown _) = do
471 val'@(TypedValue _ _ ty) <- infer val
519 val'@(TypedValue _ _ ty) <- infer val
472 -- Don't unify an unknown with an inferred polytype
520 -- Don't unify an unknown with an inferred polytype
473 (val'', ty') <- instantiatePolyTypeWithUnknowns val' ty
521 (val'', ty') <- instantiatePolyTypeWithUnknowns val' ty
474− ty' =?= u
522+ unifyTypes ty' u
475 return $ TypedValue True val'' ty'
523 return $ TypedValue True val'' ty'
476check' v@(NumericLiteral (Left _)) t | t == tyInt =
524check' v@(NumericLiteral (Left _)) t | t == tyInt =
477 return $ TypedValue True v t
525 return $ TypedValue True v t
@@ -484,11 +532,11 @@ check' v@(CharLiteral _) t | t == tyChar =
484check' v@(BooleanLiteral _) t | t == tyBoolean =
532check' v@(BooleanLiteral _) t | t == tyBoolean =
485 return $ TypedValue True v t
533 return $ TypedValue True v t
486check' (ArrayLiteral vals) t@(TypeApp a ty) = do
534check' (ArrayLiteral vals) t@(TypeApp a ty) = do
487− a =?= tyArray
535+ unifyTypes a tyArray
488 array <- ArrayLiteral <$> forM vals (`check` ty)
536 array <- ArrayLiteral <$> forM vals (`check` ty)
489 return $ TypedValue True array t
537 return $ TypedValue True array t
490check' (Abs (Left arg) ret) ty@(TypeApp (TypeApp t argTy) retTy) = do
538check' (Abs (Left arg) ret) ty@(TypeApp (TypeApp t argTy) retTy) = do
491− t =?= tyFunction
539+ unifyTypes t tyFunction
492 Just moduleName <- checkCurrentModule <$> get
540 Just moduleName <- checkCurrentModule <$> get
493 ret' <- withBindingGroupVisible $ bindLocalVariables moduleName [(arg, argTy, Defined)] $ check ret retTy
541 ret' <- withBindingGroupVisible $ bindLocalVariables moduleName [(arg, argTy, Defined)] $ check ret retTy
494 return $ TypedValue True (Abs (Left arg) ret') ty
542 return $ TypedValue True (Abs (Left arg) ret') ty
@@ -517,7 +565,7 @@ check' (SuperClassDictionary className tys) _ = do
517 return $ TypeClassDictionary (className, tys) dicts
565 return $ TypeClassDictionary (className, tys) dicts
518check' (TypedValue checkType val ty1) ty2 = do
566check' (TypedValue checkType val ty1) ty2 = do
519 Just moduleName <- checkCurrentModule <$> get
567 Just moduleName <- checkCurrentModule <$> get
520− (kind, args) <- liftCheck $ kindOfWithScopedVars ty1
568+ (kind, args) <- kindOfWithScopedVars ty1
521 checkTypeKind ty1 kind
569 checkTypeKind ty1 kind
522 ty1' <- introduceSkolemScope <=< replaceAllTypeSynonyms <=< replaceTypeWildcards $ ty1
570 ty1' <- introduceSkolemScope <=< replaceAllTypeSynonyms <=< replaceTypeWildcards $ ty1
523 ty2' <- introduceSkolemScope <=< replaceAllTypeSynonyms <=< replaceTypeWildcards $ ty2
571 ty2' <- introduceSkolemScope <=< replaceAllTypeSynonyms <=< replaceTypeWildcards $ ty2
@@ -549,12 +597,12 @@ check' e@(ObjectUpdate obj ps) t@(TypeApp o row) | o == tyObject = do
549 -- We check _obj_ against the type _t_ with the types in _ps_ replaced with unknowns.
597 -- We check _obj_ against the type _t_ with the types in _ps_ replaced with unknowns.
550 let (propsToCheck, rest) = rowToList row
598 let (propsToCheck, rest) = rowToList row
551 (removedProps, remainingProps) = partition (\(p, _) -> p `elem` map fst ps) propsToCheck
599 (removedProps, remainingProps) = partition (\(p, _) -> p `elem` map fst ps) propsToCheck
552− us <- zip (map fst removedProps) <$> replicateM (length ps) fresh
600+ us <- zip (map fst removedProps) <$> replicateM (length ps) freshType
553 obj' <- check obj (TypeApp tyObject (rowFromList (us ++ remainingProps, rest)))
601 obj' <- check obj (TypeApp tyObject (rowFromList (us ++ remainingProps, rest)))
554 ps' <- checkProperties e ps row True
602 ps' <- checkProperties e ps row True
555 return $ TypedValue True (ObjectUpdate obj' ps') t
603 return $ TypedValue True (ObjectUpdate obj' ps') t
556check' (Accessor prop val) ty = rethrow (addHint (ErrorCheckingAccessor val prop)) $ do
604check' (Accessor prop val) ty = rethrow (addHint (ErrorCheckingAccessor val prop)) $ do
557− rest <- fresh
605+ rest <- freshType
558 val' <- check val (TypeApp tyObject (RCons prop ty rest))
606 val' <- check val (TypeApp tyObject (RCons prop ty rest))
559 return $ TypedValue True (Accessor prop val') ty
607 return $ TypedValue True (Accessor prop val') ty
560check' v@(Constructor c) ty = do
608check' v@(Constructor c) ty = do
@@ -588,12 +636,18 @@ check' val ty = do
589-- The @lax@ parameter controls whether or not every record member has to be provided. For object updates, this is not the case.
637-- The @lax@ parameter controls whether or not every record member has to be provided. For object updates, this is not the case.
591−checkProperties :: Expr -> [(String, Expr)] -> Type -> Bool -> UnifyT Type Check [(String, Expr)]
639+checkProperties ::
640+ (Functor m, Applicative m, MonadState CheckState m, MonadError MultipleErrors m, MonadWriter MultipleErrors m) =>
592checkProperties expr ps row lax = let (ts, r') = rowToList row in go ps ts r' where
646checkProperties expr ps row lax = let (ts, r') = rowToList row in go ps ts r' where
593 go [] [] REmpty = return []
647 go [] [] REmpty = return []
594 go [] [] u@(TUnknown _)
648 go [] [] u@(TUnknown _)
595 | lax = return []
649 | lax = return []
596− | otherwise = do u =?= REmpty
650+ | otherwise = do unifyTypes u REmpty
597 return []
651 return []
598 go [] [] Skolem{} | lax = return []
652 go [] [] Skolem{} | lax = return []
599 go [] ((p, _): _) _ | lax = return []
653 go [] ((p, _): _) _ | lax = return []
@@ -603,8 +657,8 @@ checkProperties expr ps row lax = let (ts, r') = rowToList row in go ps ts r' wh
603 case lookup p ts of
657 case lookup p ts of
604 Nothing -> do
658 Nothing -> do
605 v'@(TypedValue _ _ ty) <- infer v
659 v'@(TypedValue _ _ ty) <- infer v
606− rest <- fresh
660+ rest <- freshType
607− r =?= RCons p ty rest
661+ unifyTypes r (RCons p ty rest)
608 ps'' <- go ps' ts rest
662 ps'' <- go ps' ts rest
609 return $ (p, v') : ps''
663 return $ (p, v') : ps''
610 Just ty -> do
664 Just ty -> do
@@ -613,20 +667,28 @@ checkProperties expr ps row lax = let (ts, r') = rowToList row in go ps ts r' wh
613 return $ (p, v') : ps''
667 return $ (p, v') : ps''
614 go _ _ _ = throwError . errorMessage $ ExprDoesNotHaveType expr (TypeApp tyObject row)
668 go _ _ _ = throwError . errorMessage $ ExprDoesNotHaveType expr (TypeApp tyObject row)
617−-- Check the type of a function application, rethrowing errors to provide a better error message
670+-- | Check the type of a function application, rethrowing errors to provide a better error message
619−checkFunctionApplication :: Expr -> Type -> Expr -> Maybe Type -> UnifyT Type Check (Type, Expr)
671+checkFunctionApplication ::
672+ (Functor m, Applicative m, MonadState CheckState m, MonadError MultipleErrors m, MonadWriter MultipleErrors m) =>
620checkFunctionApplication fn fnTy arg ret = rethrow (addHint (ErrorInApplication fn fnTy arg)) $ do
678checkFunctionApplication fn fnTy arg ret = rethrow (addHint (ErrorInApplication fn fnTy arg)) $ do
621− subst <- unifyCurrentSubstitution <$> UnifyT get
679+ subst <- gets checkSubstitution
622− checkFunctionApplication' fn (subst $? fnTy) arg (($?) subst <$> ret)
680+ checkFunctionApplication' fn (substituteType subst fnTy) arg (substituteType subst <$> ret)
625−-- Check the type of a function application
682+-- | Check the type of a function application
627−checkFunctionApplication' :: Expr -> Type -> Expr -> Maybe Type -> UnifyT Type Check (Type, Expr)
683+checkFunctionApplication' ::
684+ (Functor m, Applicative m, MonadState CheckState m, MonadError MultipleErrors m, MonadWriter MultipleErrors m) =>
628checkFunctionApplication' fn (TypeApp (TypeApp tyFunction' argTy) retTy) arg ret = do
690checkFunctionApplication' fn (TypeApp (TypeApp tyFunction' argTy) retTy) arg ret = do
629− tyFunction' =?= tyFunction
691+ unifyTypes tyFunction' tyFunction
630 arg' <- check arg argTy
692 arg' <- check arg argTy
631 case ret of
693 case ret of
632 Nothing -> return (retTy, App fn arg')
694 Nothing -> return (retTy, App fn arg')
@@ -642,8 +704,8 @@ checkFunctionApplication' fn u@(TUnknown _) arg ret = do
642 (arg'', t') <- instantiatePolyTypeWithUnknowns arg' t
704 (arg'', t') <- instantiatePolyTypeWithUnknowns arg' t
643 return $ TypedValue True arg'' t'
705 return $ TypedValue True arg'' t'
644 let ty = (\(TypedValue _ _ t) -> t) arg'
706 let ty = (\(TypedValue _ _ t) -> t) arg'
645− ret' <- maybe fresh return ret
707+ ret' <- maybe freshType return ret
646− u =?= function ty ret'
708+ unifyTypes u (function ty ret')
647 return (ret', App fn arg')
709 return (ret', App fn arg')
648checkFunctionApplication' fn (KindedType ty _) arg ret =
710checkFunctionApplication' fn (KindedType ty _) arg ret =
649 checkFunctionApplication fn ty arg ret
711 checkFunctionApplication fn ty arg ret
@@ -654,11 +716,15 @@ checkFunctionApplication' fn fnTy dict@TypeClassDictionary{} _ =
654 return (fnTy, App fn dict)
716 return (fnTy, App fn dict)
655checkFunctionApplication' _ fnTy arg _ = throwError . errorMessage $ CannotApplyFunction fnTy arg
717checkFunctionApplication' _ fnTy arg _ = throwError . errorMessage $ CannotApplyFunction fnTy arg
658−-- Compute the meet of two types, i.e. the most general type which both types subsume.
719+-- | Compute the meet of two types, i.e. the most general type which both types subsume.
659−-- TODO: handle constrained types
720+-- TODO: is this really needed?
722+ (Functor m, Applicative m, MonadState CheckState m, MonadError MultipleErrors m) =>
661−meet :: Expr -> Expr -> Type -> Type -> UnifyT Type Check (Expr, Expr, Type)
727+ m (Expr, Expr, Type)
662meet e1 e2 (ForAll ident t1 _) t2 = do
728meet e1 e2 (ForAll ident t1 _) t2 = do
663 t1' <- replaceVarWithUnknown ident t1
729 t1' <- replaceVarWithUnknown ident t1
664 meet e1 e2 t1' t2
730 meet e1 e2 t1' t2
@@ -666,7 +732,7 @@ meet e1 e2 t1 (ForAll ident t2 _) = do
666 t2' <- replaceVarWithUnknown ident t2
732 t2' <- replaceVarWithUnknown ident t2
667 meet e1 e2 t1 t2'
733 meet e1 e2 t1 t2'
668meet e1 e2 t1 t2 = do
734meet e1 e2 t1 t2 = do
669− t1 =?= t2
735+ unifyTypes t1 t2
670 return (e1, e2, t1)
736 return (e1, e2, t1)