@@ -303,18 +303,20 @@ infer' (Abs args ret) = do
303303 ts <- replicateM (length args) fresh
304304 moduleName <- substCurrentModule <$> ask
305305 bindLocalVariables moduleName (zip args ts) $ do
306− (TypedValue body bodyTy) <- infer' ret
306+ body@(TypedValue _ bodyTy) <- infer' ret
307307 return $ TypedValue (Abs args body) $ Function ts bodyTy
308308infer' (App f args) = do
309− (TypedValue f' ft) <- infer f
309+ f'@(TypedValue _ ft) <- infer f
310310 ret <- fresh
311− args' <- checkFunctionApplication ft args ret
312− return $ TypedValue (App f' args') ret
311+ app <- checkFunctionApplication f' ft args ret
312+ return $ TypedValue app ret
313313infer' (Var var) = do
314314 moduleName <- substCurrentModule <$> ask
315315 ty <- lookupVariable moduleName var
316316 ty' <- replaceAllTypeSynonyms ty
317− return $ TypedValue (Var var) ty'
317+ case ty' of
318+ ConstrainedType constraints _ -> return $ TypedValue (App (Var var) [TypeClassDictionary constraints]) ty'
319+ _ -> return $ TypedValue (Var var) ty'
318320infer' (Block ss) = do
319321 ret <- fresh
320322 (allCodePathsReturn, _, ss') <- checkBlock M.empty ret ss
@@ -343,7 +345,8 @@ infer' (TypedValue val ty) = do
343345 kind <- liftCheck $ kindOf moduleName ty
344346 guardWith ("Expected type of kind *, was " ++ prettyPrintKind kind) $ kind == Star
345347 ty' <- replaceAllTypeSynonyms ty
346− check val ty'
348+ val' <- check val ty'
349+ return $ TypedValue val' ty
347350infer' _ = error "Invalid argument to infer"
348351
349352inferProperty :: Type -> String -> Subst (Maybe Type)
@@ -589,6 +592,9 @@ check' :: Value -> Type -> Subst Value
589592check' val (ForAll idents ty) = do
590593 sk <- skolemize idents ty
591594 check val sk
595+check' val (ConstrainedType constraints ty) = do
596+ val' <- check val ty
597+ return $ Abs [Ident "__dict"] val'
592598check' val u@(TUnknown _) = do
593599 val'@(TypedValue _ ty) <- infer val
594600 -- Don't unify an unknown with an inferred polytype
@@ -612,8 +618,8 @@ check' (Abs args ret) (Function argTys retTy) = do
612618 return $ Abs args ret'
613619check' (App f args) ret = do
614620 f'@(TypedValue _ ft) <- infer f
615− args' <- checkFunctionApplication ft args ret
616− return $ App f' args'
621+ app <- checkFunctionApplication f' ft args ret
622+ return $ app
617623check' (Var var) ty = do
618624 moduleName <- substCurrentModule <$> ask
619625 ty1 <- lookupVariable moduleName var
@@ -701,33 +707,34 @@ checkProperties ps row lax = let (ts, r') = rowToList row in go ps ts r' where
701707 return $ (p, v') : ps''
702708 go _ _ _ = throwError $ prettyPrintValue (ObjectLiteral ps) ++ " does not have type " ++ prettyPrintType (Object row)
703709
704−checkFunctionApplication :: Type -> [Value] -> Type -> Subst [Value]
705−checkFunctionApplication fnTy args ret = rethrow errorMessage $ checkFunctionApplication' fnTy args ret
710+checkFunctionApplication :: Value -> Type -> [Value] -> Type -> Subst Value
711+checkFunctionApplication fn fnTy args ret = rethrow errorMessage $ checkFunctionApplication' fn fnTy args ret
706712 where
707713 errorMessage msg = "Error applying function of type "
708714 ++ prettyPrintType fnTy
709715 ++ " to arguments " ++ intercalate ", " (map prettyPrintValue args)
710− ++ ", expecting value of type "
711− ++ prettyPrintType ret ++ ":\n" ++ msg
716+ ++ ":\n" ++ msg
712717
713−checkFunctionApplication' :: Type -> [Value] -> Type -> Subst [Value]
714−checkFunctionApplication' (Function argTys retTy) args ret = do
718+checkFunctionApplication' :: Value -> Type -> [Value] -> Type -> Subst Value
719+checkFunctionApplication' fn (Function argTys retTy) args ret = do
715720 guardWith "Incorrect number of function arguments" (length args == length argTys)
716721 args' <- zipWithM check args argTys
717722 retTy `subsumes` ret
718− return args'
719−checkFunctionApplication' (ForAll ident ty) args ret = do
723+ return $ App fn args'
724+checkFunctionApplication' fn (ForAll ident ty) args ret = do
720725 replaced <- replaceVarWithUnknown ident ty
721− checkFunctionApplication replaced args ret
722−checkFunctionApplication' u@(TUnknown _) args ret = do
726+ checkFunctionApplication fn replaced args ret
727+checkFunctionApplication' fn u@(TUnknown _) args ret = do
723728 args' <- mapM (\arg -> infer arg >>= \(TypedValue v t) -> TypedValue v <$> replaceAllVarsWithUnknowns t) args
724729 let tys = map (\(TypedValue _ t) -> t) args'
725730 u ~~ Function tys ret
726− return args'
727−checkFunctionApplication' (SaturatedTypeSynonym name tyArgs) args ret = do
731+ return $ App fn args'
732+checkFunctionApplication' fn (SaturatedTypeSynonym name tyArgs) args ret = do
728733 ty <- expandTypeSynonym name tyArgs
729− checkFunctionApplication' ty args ret
730−checkFunctionApplication' fnTy args ret = throwError $ "Applying a function of type "
734+ checkFunctionApplication fn ty args ret
735+checkFunctionApplication' fn (ConstrainedType constraints fnTy) args ret = do
736+ checkFunctionApplication' (App fn [TypeClassDictionary constraints]) fnTy args ret
737+checkFunctionApplication' _ fnTy args ret = throwError $ "Applying a function of type "
731738 ++ prettyPrintType fnTy
732739 ++ " to argument(s) " ++ intercalate ", " (map prettyPrintValue args)
733740 ++ " does not yield a value of type " ++ prettyPrintType ret ++ "."