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