@@ -303,18 +303,20 @@ infer' (Abs args ret) = do
303 ts <- replicateM (length args) fresh
303 ts <- replicateM (length args) fresh
304 moduleName <- substCurrentModule <$> ask
304 moduleName <- substCurrentModule <$> ask
305 bindLocalVariables moduleName (zip args ts) $ do
305 bindLocalVariables moduleName (zip args ts) $ do
306− (TypedValue body bodyTy) <- infer' ret
306+ body@(TypedValue _ bodyTy) <- infer' ret
307 return $ TypedValue (Abs args body) $ Function ts bodyTy
307 return $ TypedValue (Abs args body) $ Function ts bodyTy
308infer' (App f args) = do
308infer' (App f args) = do
309− (TypedValue f' ft) <- infer f
309+ f'@(TypedValue _ ft) <- infer f
310 ret <- fresh
310 ret <- fresh
311− args' <- checkFunctionApplication ft args ret
311+ app <- checkFunctionApplication f' ft args ret
312− return $ TypedValue (App f' args') ret
312+ return $ TypedValue app ret
313infer' (Var var) = do
313infer' (Var var) = do
314 moduleName <- substCurrentModule <$> ask
314 moduleName <- substCurrentModule <$> ask
315 ty <- lookupVariable moduleName var
315 ty <- lookupVariable moduleName var
316 ty' <- replaceAllTypeSynonyms ty
316 ty' <- replaceAllTypeSynonyms ty
318+ ConstrainedType constraints _ -> return $ TypedValue (App (Var var) [TypeClassDictionary constraints]) ty'
317− return $ TypedValue (Var var) ty'
319+ _ -> return $ TypedValue (Var var) ty'
318infer' (Block ss) = do
320infer' (Block ss) = do
319 ret <- fresh
321 ret <- fresh
320 (allCodePathsReturn, _, ss') <- checkBlock M.empty ret ss
322 (allCodePathsReturn, _, ss') <- checkBlock M.empty ret ss
@@ -343,7 +345,8 @@ infer' (TypedValue val ty) = do
343 kind <- liftCheck $ kindOf moduleName ty
345 kind <- liftCheck $ kindOf moduleName ty
344 guardWith ("Expected type of kind *, was " ++ prettyPrintKind kind) $ kind == Star
346 guardWith ("Expected type of kind *, was " ++ prettyPrintKind kind) $ kind == Star
345 ty' <- replaceAllTypeSynonyms ty
347 ty' <- replaceAllTypeSynonyms ty
346− check val ty'
348+ val' <- check val ty'
349+ return $ TypedValue val' ty
347infer' _ = error "Invalid argument to infer"
350infer' _ = error "Invalid argument to infer"
349inferProperty :: Type -> String -> Subst (Maybe Type)
352inferProperty :: Type -> String -> Subst (Maybe Type)
@@ -589,6 +592,9 @@ check' :: Value -> Type -> Subst Value
589check' val (ForAll idents ty) = do
592check' val (ForAll idents ty) = do
590 sk <- skolemize idents ty
593 sk <- skolemize idents ty
591 check val sk
594 check val sk
595+check' val (ConstrainedType constraints ty) = do
596+ val' <- check val ty
597+ return $ Abs [Ident "__dict"] val'
592check' val u@(TUnknown _) = do
598check' val u@(TUnknown _) = do
593 val'@(TypedValue _ ty) <- infer val
599 val'@(TypedValue _ ty) <- infer val
594 -- Don't unify an unknown with an inferred polytype
600 -- Don't unify an unknown with an inferred polytype
@@ -612,8 +618,8 @@ check' (Abs args ret) (Function argTys retTy) = do
612 return $ Abs args ret'
618 return $ Abs args ret'
613check' (App f args) ret = do
619check' (App f args) ret = do
614 f'@(TypedValue _ ft) <- infer f
620 f'@(TypedValue _ ft) <- infer f
615− args' <- checkFunctionApplication ft args ret
621+ app <- checkFunctionApplication f' ft args ret
616− return $ App f' args'
622+ return $ app
617check' (Var var) ty = do
623check' (Var var) ty = do
618 moduleName <- substCurrentModule <$> ask
624 moduleName <- substCurrentModule <$> ask
619 ty1 <- lookupVariable moduleName var
625 ty1 <- lookupVariable moduleName var
@@ -701,33 +707,34 @@ checkProperties ps row lax = let (ts, r') = rowToList row in go ps ts r' where
701 return $ (p, v') : ps''
707 return $ (p, v') : ps''
702 go _ _ _ = throwError $ prettyPrintValue (ObjectLiteral ps) ++ " does not have type " ++ prettyPrintType (Object row)
708 go _ _ _ = throwError $ prettyPrintValue (ObjectLiteral ps) ++ " does not have type " ++ prettyPrintType (Object row)
704−checkFunctionApplication :: Type -> [Value] -> Type -> Subst [Value]
710+checkFunctionApplication :: Value -> Type -> [Value] -> Type -> Subst Value
705−checkFunctionApplication fnTy args ret = rethrow errorMessage $ checkFunctionApplication' fnTy args ret
711+checkFunctionApplication fn fnTy args ret = rethrow errorMessage $ checkFunctionApplication' fn fnTy args ret
707 errorMessage msg = "Error applying function of type "
713 errorMessage msg = "Error applying function of type "
708 ++ prettyPrintType fnTy
714 ++ prettyPrintType fnTy
709 ++ " to arguments " ++ intercalate ", " (map prettyPrintValue args)
715 ++ " to arguments " ++ intercalate ", " (map prettyPrintValue args)
710− ++ ", expecting value of type "
716+ ++ ":\n" ++ msg
711− ++ prettyPrintType ret ++ ":\n" ++ msg
713−checkFunctionApplication' :: Type -> [Value] -> Type -> Subst [Value]
718+checkFunctionApplication' :: Value -> Type -> [Value] -> Type -> Subst Value
714−checkFunctionApplication' (Function argTys retTy) args ret = do
719+checkFunctionApplication' fn (Function argTys retTy) args ret = do
715 guardWith "Incorrect number of function arguments" (length args == length argTys)
720 guardWith "Incorrect number of function arguments" (length args == length argTys)
716 args' <- zipWithM check args argTys
721 args' <- zipWithM check args argTys
717 retTy `subsumes` ret
722 retTy `subsumes` ret
718− return args'
723+ return $ App fn args'
719−checkFunctionApplication' (ForAll ident ty) args ret = do
724+checkFunctionApplication' fn (ForAll ident ty) args ret = do
720 replaced <- replaceVarWithUnknown ident ty
725 replaced <- replaceVarWithUnknown ident ty
721− checkFunctionApplication replaced args ret
726+ checkFunctionApplication fn replaced args ret
722−checkFunctionApplication' u@(TUnknown _) args ret = do
727+checkFunctionApplication' fn u@(TUnknown _) args ret = do
723 args' <- mapM (\arg -> infer arg >>= \(TypedValue v t) -> TypedValue v <$> replaceAllVarsWithUnknowns t) args
728 args' <- mapM (\arg -> infer arg >>= \(TypedValue v t) -> TypedValue v <$> replaceAllVarsWithUnknowns t) args
724 let tys = map (\(TypedValue _ t) -> t) args'
729 let tys = map (\(TypedValue _ t) -> t) args'
725 u ~~ Function tys ret
730 u ~~ Function tys ret
726− return args'
731+ return $ App fn args'
727−checkFunctionApplication' (SaturatedTypeSynonym name tyArgs) args ret = do
732+checkFunctionApplication' fn (SaturatedTypeSynonym name tyArgs) args ret = do
728 ty <- expandTypeSynonym name tyArgs
733 ty <- expandTypeSynonym name tyArgs
729− checkFunctionApplication' ty args ret
734+ checkFunctionApplication fn ty args ret
735+checkFunctionApplication' fn (ConstrainedType constraints fnTy) args ret = do
736+ checkFunctionApplication' (App fn [TypeClassDictionary constraints]) fnTy args ret
730−checkFunctionApplication' fnTy args ret = throwError $ "Applying a function of type "
737+checkFunctionApplication' _ fnTy args ret = throwError $ "Applying a function of type "
731 ++ prettyPrintType fnTy
738 ++ prettyPrintType fnTy
732 ++ " to argument(s) " ++ intercalate ", " (map prettyPrintValue args)
739 ++ " to argument(s) " ++ intercalate ", " (map prettyPrintValue args)
733 ++ " does not yield a value of type " ++ prettyPrintType ret ++ "."
740 ++ " does not yield a value of type " ++ prettyPrintType ret ++ "."