@@ -14,6 +14,7 @@
1414-----------------------------------------------------------------------------
1515
1616{-# LANGUAGE FlexibleContexts #-}
17+{-# LANGUAGE ScopedTypeVariables #-}
1718{-# LANGUAGE MultiParamTypeClasses #-}
1819{-# LANGUAGE OverloadedStrings #-}
1920
@@ -46,10 +47,9 @@ import Data.Maybe (fromMaybe)
4647import qualified Data.Map as M
4748
4849import Control.Monad
49−import Control.Monad.State
50−import Control.Monad.Unify
50+import Control.Monad.State.Class (MonadState(..), gets)
5151import Control.Monad.Error.Class (MonadError(..))
52−import Control.Monad.Writer.Class (tell)
52+import Control.Monad.Writer.Class (MonadWriter(..))
5353
5454import Language.PureScript.Crash
5555import Language.PureScript.AST
@@ -69,11 +69,13 @@ import Language.PureScript.TypeChecker.Unify
6969import Language.PureScript.TypeClassDictionaries
7070import Language.PureScript.Types
7171
72−-- |
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
7473-- type class dictionaries and type annotations.
75−--
76−typesOf :: ModuleName -> [(Ident, Expr)] -> Check [(Ident, (Expr, Type))]
74+typesOf ::
75+ (Functor m, Applicative m, MonadState CheckState m, MonadError MultipleErrors m, MonadWriter MultipleErrors m) =>
76+ ModuleName ->
77+ [(Ident, Expr)] ->
78+ m [(Ident, (Expr, Type))]
7779typesOf moduleName vals = do
7880 tys <- fmap tidyUp . liftUnifyWarnings replace $ do
7981 (untyped, typed, dict, untypedDict) <- typeDictionaryForBindingGroup moduleName vals
@@ -91,17 +93,21 @@ typesOf moduleName vals = do
9193 return (ident, (val', varIfUnknown ty))
9294 where
9395 -- 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
9597 -- Replace all the wildcards types with their inferred types
96− replace sub (ErrorMessage hints (WildcardInferredType ty)) = ErrorMessage hints $ WildcardInferredType (sub $? ty)
97− replace sub (ErrorMessage hints (MissingTypeDeclaration name ty)) = ErrorMessage hints $ MissingTypeDeclaration name (varIfUnknown (sub $? ty))
98+ replace sub (ErrorMessage hints (WildcardInferredType ty)) = ErrorMessage hints . WildcardInferredType $ substituteType sub ty
99+ replace sub (ErrorMessage hints (MissingTypeDeclaration name ty)) = ErrorMessage hints $ MissingTypeDeclaration name (varIfUnknown (substituteType sub ty))
98100 replace _ em = em
99101
100102type TypeData = M.Map (ModuleName, Ident) (Type, NameKind, NameVisibility)
101103
102104type UntypedData = [(Ident, Type)]
103105
104−typeDictionaryForBindingGroup :: ModuleName -> [(Ident, Expr)] -> UnifyT Type Check ([(Ident, Expr)], [(Ident, (Expr, Type, Bool))], TypeData, UntypedData)
106+typeDictionaryForBindingGroup ::
107+ (Functor m, Applicative m, MonadState CheckState m, MonadError MultipleErrors m, MonadWriter MultipleErrors m) =>
108+ ModuleName ->
109+ [(Ident, Expr)] ->
110+ m ([(Ident, Expr)], [(Ident, (Expr, Type, Bool))], TypeData, UntypedData)
105111typeDictionaryForBindingGroup moduleName vals = do
106112 let
107113 -- 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
113119 typedDict = map (\(ident, (_, ty, _)) -> (ident, ty)) typed
114120
115121 -- Create fresh unification variables for the types of untyped declarations
116− untypedNames <- replicateM (length untyped) fresh
122+ untypedNames <- replicateM (length untyped) freshType
117123
118124 let
119125 -- Make a map of names to the unification variables of untyped declarations
@@ -122,12 +128,17 @@ typeDictionaryForBindingGroup moduleName vals = do
122128 dict = M.fromList (map (\(ident, ty) -> ((moduleName, ident), (ty, Private, Undefined))) $ typedDict ++ untypedDict)
123129 return (untyped, typed, dict, untypedDict)
124130
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) =>
133+ ModuleName ->
134+ (Ident, (Expr, Type, Bool)) ->
135+ TypeData ->
136+ m (Ident, (Expr, Type))
126137checkTypedBindingGroupElement mn (ident, (val', ty, checkType)) dict = do
127138 -- Replace type wildcards
128139 ty' <- replaceTypeWildcards ty
129140 -- Kind check
130− (kind, args) <- liftCheck $ kindOfWithScopedVars ty
141+ (kind, args) <- kindOfWithScopedVars ty
131142 checkTypeKind ty kind
132143 -- Check the type with the new names in scope
133144 ty'' <- introduceSkolemScope <=< replaceAllTypeSynonyms <=< replaceTypeWildcards $ ty'
@@ -136,17 +147,21 @@ checkTypedBindingGroupElement mn (ident, (val', ty, checkType)) dict = do
136147 else return (TypedValue False val' ty'')
137148 return (ident, (val'', ty''))
138149
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) =>
152+ Bool ->
153+ (Ident, Expr) ->
154+ TypeData ->
155+ UntypedData ->
156+ m (Ident, (Expr, Type))
140157typeForBindingGroupElement warn (ident, val) dict untypedDict = do
141158 -- Infer the type with the new names in scope
142159 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)
144161 when warn . tell . errorMessage $ MissingTypeDeclaration ident ty
145162 return (ident, (TypedValue True val' ty, ty))
146163
147−-- |
148−-- Check if a value contains a type annotation
149−--
164+-- | Check if a value contains a type annotation
150165isTyped :: (Ident, Expr) -> Either (Ident, Expr) (Ident, (Expr, Type, Bool))
151166isTyped (name, TypedValue checkType value ty) = Right (name, (value, ty, checkType))
152167isTyped (name, value) = Left (name, value)
@@ -162,10 +177,12 @@ overTypes f = let (_, f', _) = everywhereOnValues id g id in f'
162177 g (TypeClassDictionary (nm, tys) sco) = TypeClassDictionary (nm, map f tys) sco
163178 g other = other
164179
165−-- |
166−-- Replace type class dictionary placeholders with inferred type class dictionaries
167−--
168−replaceTypeClassDictionaries :: ModuleName -> Expr -> Check Expr
180+-- | Replace type class dictionary placeholders with inferred type class dictionaries
181+replaceTypeClassDictionaries ::
182+ (Functor m, Applicative m, MonadState CheckState m, MonadError MultipleErrors m, MonadWriter MultipleErrors m) =>
183+ ModuleName ->
184+ Expr ->
185+ m Expr
169186replaceTypeClassDictionaries mn =
170187 let (_, f, _) = everywhereOnValuesTopDownM return go return
171188 in f
@@ -173,20 +190,24 @@ replaceTypeClassDictionaries mn =
173190 go (TypeClassDictionary constraint dicts) = entails mn dicts constraint
174191 go other = return other
175192
176−-- |
177−-- Check the kind of a type, failing if it is not of kind *.
178−--
179−checkTypeKind :: Type -> Kind -> UnifyT t Check ()
193+-- | Check the kind of a type, failing if it is not of kind *.
194+checkTypeKind ::
195+ (Functor m, Applicative m, MonadState CheckState m, MonadError MultipleErrors m) =>
196+ Type ->
197+ Kind ->
198+ m ()
180199checkTypeKind ty kind = guardWith (errorMessage (ExpectedType ty kind)) $ kind == Star
181200
182−-- |
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
184202-- or TypeClassDictionary values.
185203--
186204-- This is necessary during type checking to avoid unifying a polymorphic type with a
187205-- unification variable.
188−--
189−instantiatePolyTypeWithUnknowns :: Expr -> Type -> UnifyT Type Check (Expr, Type)
206+instantiatePolyTypeWithUnknowns ::
207+ (Functor m, Applicative m, MonadState CheckState m, MonadError MultipleErrors m) =>
208+ Expr ->
209+ Type ->
210+ m (Expr, Type)
190211instantiatePolyTypeWithUnknowns val (ForAll ident ty _) = do
191212 ty' <- replaceVarWithUnknown ident ty
192213 instantiatePolyTypeWithUnknowns val ty'
@@ -196,16 +217,18 @@ instantiatePolyTypeWithUnknowns val (ConstrainedType constraints ty) = do
196217 return (foldl App val (map (flip TypeClassDictionary dicts) constraints), ty')
197218instantiatePolyTypeWithUnknowns val ty = return (val, ty)
198219
199−-- |
200−-- Infer a type for a value, rethrowing any error to provide a more useful error message
201−--
202−infer :: Expr -> UnifyT Type Check Expr
220+-- | Infer a type for a value, rethrowing any error to provide a more useful error message
221+infer ::
222+ (Functor m, Applicative m, MonadState CheckState m, MonadError MultipleErrors m, MonadWriter MultipleErrors m) =>
223+ Expr ->
224+ m Expr
203225infer val = rethrow (addHint (ErrorInferringType val)) $ infer' val
204226
205−-- |
206−-- Infer a type for a value
207−--
208−infer' :: Expr -> UnifyT Type Check Expr
227+-- | Infer a type for a value
228+infer' ::
229+ (Functor m, Applicative m, MonadState CheckState m, MonadError MultipleErrors m, MonadWriter MultipleErrors m) =>
230+ Expr ->
231+ m Expr
209232infer' v@(NumericLiteral (Left _)) = return $ TypedValue True v tyInt
210233infer' v@(NumericLiteral (Right _)) = return $ TypedValue True v tyNumber
211234infer' v@(StringLiteral _) = return $ TypedValue True v tyString
@@ -213,8 +236,8 @@ infer' v@(CharLiteral _) = return $ TypedValue True v tyChar
213236infer' v@(BooleanLiteral _) = return $ TypedValue True v tyBoolean
214237infer' (ArrayLiteral vals) = do
215238 ts <- traverse infer vals
216− els <- fresh
217− forM_ ts $ \(TypedValue _ _ t) -> els =?= t
239+ els <- freshType
240+ forM_ ts $ \(TypedValue _ _ t) -> unifyTypes els t
218241 return $ TypedValue True (ArrayLiteral ts) (TypeApp tyArray els)
219242infer' (ObjectLiteral ps) = do
220243 ensureNoDuplicateProperties ps
@@ -224,20 +247,20 @@ infer' (ObjectLiteral ps) = do
224247 return $ TypedValue True (ObjectLiteral (zip (map fst ps) ts)) ty
225248infer' (ObjectUpdate o ps) = do
226249 ensureNoDuplicateProperties ps
227− row <- fresh
250+ row <- freshType
228251 newVals <- zipWith (\(name, _) t -> (name, t)) ps <$> traverse (infer . snd) ps
229252 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
231254 let oldTy = TypeApp tyObject $ rowFromList (oldTys, row)
232255 o' <- TypedValue True <$> check o oldTy <*> pure oldTy
233256 return $ TypedValue True (ObjectUpdate o' newVals) $ TypeApp tyObject $ rowFromList (newTys, row)
234257infer' (Accessor prop val) = rethrow (addHint (ErrorCheckingAccessor val prop)) $ do
235− field <- fresh
236− rest <- fresh
258+ field <- freshType
259+ rest <- freshType
237260 typed <- check val (TypeApp tyObject (RCons prop field rest))
238261 return $ TypedValue True (Accessor prop typed) field
239262infer' (Abs (Left arg) ret) = do
240− ty <- fresh
263+ ty <- freshType
241264 Just moduleName <- checkCurrentModule <$> get
242265 withBindingGroupVisible $ bindLocalVariables moduleName [(arg, ty, Defined)] $ do
243266 body@(TypedValue _ _ bodyTy) <- infer' ret
@@ -264,7 +287,7 @@ infer' v@(Constructor c) = do
264287 return $ TypedValue True v' ty'
265288infer' (Case vals binders) = do
266289 (vals', ts) <- instantiateForBinders vals binders
267− ret <- fresh
290+ ret <- freshType
268291 binders' <- checkBinders ts ret binders
269292 return $ TypedValue True (Case vals' binders') ret
270293infer' (IfThenElse cond th el) = do
@@ -281,7 +304,7 @@ infer' (SuperClassDictionary className tys) = do
281304 return $ TypeClassDictionary (className, tys) dicts
282305infer' (TypedValue checkType val ty) = do
283306 Just moduleName <- checkCurrentModule <$> get
284− (kind, args) <- liftCheck $ kindOfWithScopedVars ty
307+ (kind, args) <- kindOfWithScopedVars ty
285308 checkTypeKind ty kind
286309 ty' <- introduceSkolemScope <=< replaceAllTypeSynonyms <=< replaceTypeWildcards $ ty
287310 val' <- if checkType then withScopedTypeVars moduleName args (check val ty') else return val
@@ -289,22 +312,28 @@ infer' (TypedValue checkType val ty) = do
289312infer' (PositionedValue pos _ val) = warnAndRethrowWithPosition pos $ infer' val
290313infer' _ = internalError "Invalid argument to infer"
291314
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) =>
317+ [Declaration] ->
318+ [Declaration] ->
319+ Expr ->
320+ (Expr -> m Expr) ->
321+ m ([Declaration], Expr)
293322inferLetBinding seen [] ret j = (,) seen <$> withBindingGroupVisible (j ret)
294323inferLetBinding seen (ValueDeclaration ident nameKind [] (Right (tv@(TypedValue checkType val ty))) : rest) ret j = do
295324 Just moduleName <- checkCurrentModule <$> get
296− (kind, args) <- liftCheck $ kindOfWithScopedVars ty
325+ (kind, args) <- kindOfWithScopedVars ty
297326 checkTypeKind ty kind
298327 let dict = M.singleton (moduleName, ident) (ty, nameKind, Undefined)
299328 ty' <- introduceSkolemScope <=< replaceAllTypeSynonyms <=< replaceTypeWildcards $ ty
300329 TypedValue _ val' ty'' <- if checkType then withScopedTypeVars moduleName args (bindNames dict (check val ty')) else return tv
301330 bindNames (M.singleton (moduleName, ident) (ty'', nameKind, Defined)) $ inferLetBinding (seen ++ [ValueDeclaration ident nameKind [] (Right (TypedValue checkType val' ty''))]) rest ret j
302331inferLetBinding seen (ValueDeclaration ident nameKind [] (Right val) : rest) ret j = do
303− valTy <- fresh
332+ valTy <- freshType
304333 Just moduleName <- checkCurrentModule <$> get
305334 let dict = M.singleton (moduleName, ident) (valTy, nameKind, Undefined)
306335 TypedValue _ val' valTy' <- bindNames dict $ infer val
307− valTy =?= valTy'
336+ unifyTypes valTy valTy'
308337 bindNames (M.singleton (moduleName, ident) (valTy', nameKind, Defined)) $ inferLetBinding (seen ++ [ValueDeclaration ident nameKind [] (Right val')]) rest ret j
309338inferLetBinding seen (BindingGroupDeclaration ds : rest) ret j = do
310339 Just moduleName <- checkCurrentModule <$> get
@@ -320,16 +349,18 @@ inferLetBinding seen (PositionedDeclaration pos com d : ds) ret j = warnAndRethr
320349 return (PositionedDeclaration pos com d' : ds', val')
321350inferLetBinding _ _ _ _ = internalError "Invalid argument to inferLetBinding"
322351
323−-- |
324−-- Infer the types of variables brought into scope by a binder
325−--
326−inferBinder :: Type -> Binder -> UnifyT Type Check (M.Map Ident Type)
352+-- | Infer the types of variables brought into scope by a binder
353+inferBinder :: forall m.
354+ (Functor m, Applicative m, MonadState CheckState m, MonadError MultipleErrors m, MonadWriter MultipleErrors m) =>
355+ Type ->
356+ Binder ->
357+ m (M.Map Ident Type)
327358inferBinder _ NullBinder = return M.empty
328−inferBinder val (StringBinder _) = val =?= tyString >> return M.empty
329−inferBinder val (CharBinder _) = val =?= tyChar >> return M.empty
330−inferBinder val (NumberBinder (Left _)) = val =?= tyInt >> return M.empty
331−inferBinder val (NumberBinder (Right _)) = val =?= tyNumber >> return M.empty
332−inferBinder val (BooleanBinder _) = val =?= tyBoolean >> return M.empty
359+inferBinder val (StringBinder _) = unifyTypes val tyString >> return M.empty
360+inferBinder val (CharBinder _) = unifyTypes val tyChar >> return M.empty
361+inferBinder val (NumberBinder (Left _)) = unifyTypes val tyInt >> return M.empty
362+inferBinder val (NumberBinder (Right _)) = unifyTypes val tyNumber >> return M.empty
363+inferBinder val (BooleanBinder _) = unifyTypes val tyBoolean >> return M.empty
333364inferBinder val (VarBinder name) = return $ M.singleton name val
334365inferBinder val (ConstructorBinder ctor binders) = do
335366 env <- getEnv
@@ -339,7 +370,7 @@ inferBinder val (ConstructorBinder ctor binders) = do
339370 fn' <- introduceSkolemScope <=< replaceAllTypeSynonyms $ fn
340371 let (args, ret) = peelArgs fn'
341372 unless (length args == length binders) . throwError . errorMessage $ IncorrectConstructorArity ctor
342− ret =?= val
373+ unifyTypes ret val
343374 M.unions <$> zipWithM inferBinder (reverse args) binders
344375 _ -> throwError . errorMessage $ UnknownDataConstructor ctor Nothing
345376 where
@@ -349,23 +380,23 @@ inferBinder val (ConstructorBinder ctor binders) = do
349380 go args (TypeApp (TypeApp fn arg) ret) | fn == tyFunction = go (arg : args) ret
350381 go args ret = (args, ret)
351382inferBinder val (ObjectBinder props) = do
352− row <- fresh
353− rest <- fresh
383+ row <- freshType
384+ rest <- freshType
354385 m1 <- inferRowProperties row rest props
355− val =?= TypeApp tyObject row
386+ unifyTypes val (TypeApp tyObject row)
356387 return m1
357388 where
358− inferRowProperties :: Type -> Type -> [(String, Binder)] -> UnifyT Type Check (M.Map Ident Type)
359− inferRowProperties nrow row [] = nrow =?= row >> return M.empty
389+ inferRowProperties :: Type -> Type -> [(String, Binder)] -> m (M.Map Ident Type)
390+ inferRowProperties nrow row [] = unifyTypes nrow row >> return M.empty
360391 inferRowProperties nrow row ((name, binder):binders) = do
361− propTy <- fresh
392+ propTy <- freshType
362393 m1 <- inferBinder propTy binder
363394 m2 <- inferRowProperties nrow (RCons name propTy row) binders
364395 return $ m1 `M.union` m2
365396inferBinder val (ArrayBinder binders) = do
366− el <- fresh
397+ el <- freshType
367398 m1 <- M.unions <$> traverse (inferBinder el) binders
368− val =?= TypeApp tyArray el
399+ unifyTypes val (TypeApp tyArray el)
369400 return m1
370401inferBinder val (NamedBinder name binder) = do
371402 m <- inferBinder val binder
@@ -377,9 +408,9 @@ inferBinder val (PositionedBinder pos _ binder) =
377408-- and use `kindOfWithScopedVars`.
378409inferBinder val (TypedBinder ty binder) = do
379410 ty1 <- replaceAllTypeSynonyms <=< replaceTypeWildcards $ ty
380− kind <- liftCheck $ kindOf ty1
411+ kind <- kindOf ty1
381412 checkTypeKind ty1 kind
382− val =?= ty1
413+ unifyTypes val ty1
383414 inferBinder val binder
384415
385416-- | Returns true if a binder requires its argument type to be a monotype.
@@ -392,7 +423,11 @@ binderRequiresMonotype (PositionedBinder _ _ b) = binderRequiresMonotype b
392423binderRequiresMonotype _ = True
393424
394425-- | 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) =>
428+ [Expr] ->
429+ [CaseAlternative] ->
430+ m ([Expr], [Type])
396431instantiateForBinders vals cas = unzip <$> zipWithM (\val inst -> do
397432 TypedValue _ val' ty <- infer val
398433 if inst
@@ -405,7 +440,12 @@ instantiateForBinders vals cas = unzip <$> zipWithM (\val inst -> do
405440-- |
406441-- Check the types of the return values in a set of binders in a case statement
407442--
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) =>
445+ [Type] ->
446+ Type ->
447+ [CaseAlternative] ->
448+ m [CaseAlternative]
409449checkBinders _ _ [] = return []
410450checkBinders nvals ret (CaseAlternative binders result : bs) = do
411451 guardWith (errorMessage $ OverlappingArgNames Nothing) $
@@ -430,13 +470,21 @@ checkBinders nvals ret (CaseAlternative binders result : bs) = do
430470-- |
431471-- Check the type of a value, rethrowing errors to provide a better error message
432472--
433−check :: Expr -> Type -> UnifyT Type Check Expr
473+check ::
474+ (Functor m, Applicative m, MonadState CheckState m, MonadError MultipleErrors m, MonadWriter MultipleErrors m) =>
475+ Expr ->
476+ Type ->
477+ m Expr
434478check val ty = rethrow (addHint (ErrorCheckingType val ty)) $ check' val ty
435479
436480-- |
437481-- Check the type of a value
438482--
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) =>
485+ Expr ->
486+ Type ->
487+ m Expr
440488check' val (ForAll ident ty _) = do
441489 scope <- newSkolemScope
442490 sko <- newSkolemConstant
@@ -446,15 +494,15 @@ check' val (ForAll ident ty _) = do
446494 return $ TypedValue True val' (ForAll ident ty (Just scope))
447495check' val t@(ConstrainedType constraints ty) = do
448496 dictNames <- forM constraints $ \(Qualified _ (ProperName className), _) -> do
449− n <- liftCheck freshDictionaryName
497+ n <- freshDictionaryName
450498 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
452500 val' <- withBindingGroupVisible $ withTypeClassDictionaries dicts $ check val ty
453501 return $ TypedValue True (foldr (Abs . Left) val' dictNames) t
454502 where
455503 -- | Add a dictionary for the constraint to the scope, and dictionaries
456− -- for all implies superclass instances.
457− newDictionaries :: [(Qualified ProperName, Integer)] -> Qualified Ident -> (Qualified ProperName, [Type]) -> Check [TypeClassDictionaryInScope]
504+ -- for all implied superclass instances.
505+ newDictionaries :: [(Qualified ProperName, Integer)] -> Qualified Ident -> (Qualified ProperName, [Type]) -> m [TypeClassDictionaryInScope]
458506 newDictionaries path name (className, instanceTy) = do
459507 tcs <- gets (typeClasses . checkEnv)
460508 let (args, _, superclasses) = fromMaybe (internalError "newDictionaries: type class lookup failed") $ M.lookup className tcs
@@ -471,7 +519,7 @@ check' val u@(TUnknown _) = do
471519 val'@(TypedValue _ _ ty) <- infer val
472520 -- Don't unify an unknown with an inferred polytype
473521 (val'', ty') <- instantiatePolyTypeWithUnknowns val' ty
474− ty' =?= u
522+ unifyTypes ty' u
475523 return $ TypedValue True val'' ty'
476524check' v@(NumericLiteral (Left _)) t | t == tyInt =
477525 return $ TypedValue True v t
@@ -484,11 +532,11 @@ check' v@(CharLiteral _) t | t == tyChar =
484532check' v@(BooleanLiteral _) t | t == tyBoolean =
485533 return $ TypedValue True v t
486534check' (ArrayLiteral vals) t@(TypeApp a ty) = do
487− a =?= tyArray
535+ unifyTypes a tyArray
488536 array <- ArrayLiteral <$> forM vals (`check` ty)
489537 return $ TypedValue True array t
490538check' (Abs (Left arg) ret) ty@(TypeApp (TypeApp t argTy) retTy) = do
491− t =?= tyFunction
539+ unifyTypes t tyFunction
492540 Just moduleName <- checkCurrentModule <$> get
493541 ret' <- withBindingGroupVisible $ bindLocalVariables moduleName [(arg, argTy, Defined)] $ check ret retTy
494542 return $ TypedValue True (Abs (Left arg) ret') ty
@@ -517,7 +565,7 @@ check' (SuperClassDictionary className tys) _ = do
517565 return $ TypeClassDictionary (className, tys) dicts
518566check' (TypedValue checkType val ty1) ty2 = do
519567 Just moduleName <- checkCurrentModule <$> get
520− (kind, args) <- liftCheck $ kindOfWithScopedVars ty1
568+ (kind, args) <- kindOfWithScopedVars ty1
521569 checkTypeKind ty1 kind
522570 ty1' <- introduceSkolemScope <=< replaceAllTypeSynonyms <=< replaceTypeWildcards $ ty1
523571 ty2' <- introduceSkolemScope <=< replaceAllTypeSynonyms <=< replaceTypeWildcards $ ty2
@@ -549,12 +597,12 @@ check' e@(ObjectUpdate obj ps) t@(TypeApp o row) | o == tyObject = do
549597 -- We check _obj_ against the type _t_ with the types in _ps_ replaced with unknowns.
550598 let (propsToCheck, rest) = rowToList row
551599 (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
553601 obj' <- check obj (TypeApp tyObject (rowFromList (us ++ remainingProps, rest)))
554602 ps' <- checkProperties e ps row True
555603 return $ TypedValue True (ObjectUpdate obj' ps') t
556604check' (Accessor prop val) ty = rethrow (addHint (ErrorCheckingAccessor val prop)) $ do
557− rest <- fresh
605+ rest <- freshType
558606 val' <- check val (TypeApp tyObject (RCons prop ty rest))
559607 return $ TypedValue True (Accessor prop val') ty
560608check' v@(Constructor c) ty = do
@@ -588,12 +636,18 @@ check' val ty = do
588636--
589637-- The @lax@ parameter controls whether or not every record member has to be provided. For object updates, this is not the case.
590638--
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) =>
641+ Expr ->
642+ [(String, Expr)] ->
643+ Type ->
644+ Bool ->
645+ m [(String, Expr)]
592646checkProperties expr ps row lax = let (ts, r') = rowToList row in go ps ts r' where
593647 go [] [] REmpty = return []
594648 go [] [] u@(TUnknown _)
595649 | lax = return []
596− | otherwise = do u =?= REmpty
650+ | otherwise = do unifyTypes u REmpty
597651 return []
598652 go [] [] Skolem{} | lax = return []
599653 go [] ((p, _): _) _ | lax = return []
@@ -603,8 +657,8 @@ checkProperties expr ps row lax = let (ts, r') = rowToList row in go ps ts r' wh
603657 case lookup p ts of
604658 Nothing -> do
605659 v'@(TypedValue _ _ ty) <- infer v
606− rest <- fresh
607− r =?= RCons p ty rest
660+ rest <- freshType
661+ unifyTypes r (RCons p ty rest)
608662 ps'' <- go ps' ts rest
609663 return $ (p, v') : ps''
610664 Just ty -> do
@@ -613,20 +667,28 @@ checkProperties expr ps row lax = let (ts, r') = rowToList row in go ps ts r' wh
613667 return $ (p, v') : ps''
614668 go _ _ _ = throwError . errorMessage $ ExprDoesNotHaveType expr (TypeApp tyObject row)
615669
616−-- |
617−-- Check the type of a function application, rethrowing errors to provide a better error message
618−--
619−checkFunctionApplication :: Expr -> Type -> Expr -> Maybe Type -> UnifyT Type Check (Type, Expr)
670+-- | Check the type of a function application, rethrowing errors to provide a better error message
671+checkFunctionApplication ::
672+ (Functor m, Applicative m, MonadState CheckState m, MonadError MultipleErrors m, MonadWriter MultipleErrors m) =>
673+ Expr ->
674+ Type ->
675+ Expr ->
676+ Maybe Type ->
677+ m (Type, Expr)
620678checkFunctionApplication fn fnTy arg ret = rethrow (addHint (ErrorInApplication fn fnTy arg)) $ do
621− subst <- unifyCurrentSubstitution <$> UnifyT get
622− checkFunctionApplication' fn (subst $? fnTy) arg (($?) subst <$> ret)
623−
624−-- |
625−-- Check the type of a function application
626−--
627−checkFunctionApplication' :: Expr -> Type -> Expr -> Maybe Type -> UnifyT Type Check (Type, Expr)
679+ subst <- gets checkSubstitution
680+ checkFunctionApplication' fn (substituteType subst fnTy) arg (substituteType subst <$> ret)
681+
682+-- | Check the type of a function application
683+checkFunctionApplication' ::
684+ (Functor m, Applicative m, MonadState CheckState m, MonadError MultipleErrors m, MonadWriter MultipleErrors m) =>
685+ Expr ->
686+ Type ->
687+ Expr ->
688+ Maybe Type ->
689+ m (Type, Expr)
628690checkFunctionApplication' fn (TypeApp (TypeApp tyFunction' argTy) retTy) arg ret = do
629− tyFunction' =?= tyFunction
691+ unifyTypes tyFunction' tyFunction
630692 arg' <- check arg argTy
631693 case ret of
632694 Nothing -> return (retTy, App fn arg')
@@ -642,8 +704,8 @@ checkFunctionApplication' fn u@(TUnknown _) arg ret = do
642704 (arg'', t') <- instantiatePolyTypeWithUnknowns arg' t
643705 return $ TypedValue True arg'' t'
644706 let ty = (\(TypedValue _ _ t) -> t) arg'
645− ret' <- maybe fresh return ret
646− u =?= function ty ret'
707+ ret' <- maybe freshType return ret
708+ unifyTypes u (function ty ret')
647709 return (ret', App fn arg')
648710checkFunctionApplication' fn (KindedType ty _) arg ret =
649711 checkFunctionApplication fn ty arg ret
@@ -654,11 +716,15 @@ checkFunctionApplication' fn fnTy dict@TypeClassDictionary{} _ =
654716 return (fnTy, App fn dict)
655717checkFunctionApplication' _ fnTy arg _ = throwError . errorMessage $ CannotApplyFunction fnTy arg
656718
657−-- |
658−-- Compute the meet of two types, i.e. the most general type which both types subsume.
659−-- TODO: handle constrained types
660−--
661−meet :: Expr -> Expr -> Type -> Type -> UnifyT Type Check (Expr, Expr, Type)
719+-- | Compute the meet of two types, i.e. the most general type which both types subsume.
720+-- TODO: is this really needed?
721+meet ::
722+ (Functor m, Applicative m, MonadState CheckState m, MonadError MultipleErrors m) =>
723+ Expr ->
724+ Expr ->
725+ Type ->
726+ Type ->
727+ m (Expr, Expr, Type)
662728meet e1 e2 (ForAll ident t1 _) t2 = do
663729 t1' <- replaceVarWithUnknown ident t1
664730 meet e1 e2 t1' t2
@@ -666,7 +732,7 @@ meet e1 e2 t1 (ForAll ident t2 _) = do
666732 t2' <- replaceVarWithUnknown ident t2
667733 meet e1 e2 t1 t2'
668734meet e1 e2 t1 t2 = do
669− t1 =?= t2
735+ unifyTypes t1 t2
670736 return (e1, e2, t1)
671737
672738-- |