@@ -95,15 +95,7 @@ unifyTypes t1 t2 = rethrow (\e -> "Error unifying type " ++ prettyPrintType t1 +
95 sk <- skolemize ident ty1
95 sk <- skolemize ident ty1
96 sk `unifyTypes` ty2
96 sk `unifyTypes` ty2
97 unifyTypes' ty f@(ForAll _ _) = f `unifyTypes` ty
97 unifyTypes' ty f@(ForAll _ _) = f `unifyTypes` ty
98− unifyTypes' Number Number = return ()
99− unifyTypes' String String = return ()
100− unifyTypes' Boolean Boolean = return ()
101− unifyTypes' Array Array = return ()
102 unifyTypes' (Object row1) (Object row2) = row1 ?= row2
98 unifyTypes' (Object row1) (Object row2) = row1 ?= row2
103− unifyTypes' (Function args1 ret1) (Function args2 ret2) = do
104− guardWith "Function applied to incorrect number of args" $ length args1 == length args2
105− zipWithM_ unifyTypes args1 args2
106− ret1 `unifyTypes` ret2
107 unifyTypes' (TypeVar v1) (TypeVar v2) | v1 == v2 = return ()
99 unifyTypes' (TypeVar v1) (TypeVar v2) | v1 == v2 = return ()
108 unifyTypes' (TypeConstructor c1) (TypeConstructor c2) = do
100 unifyTypes' (TypeConstructor c1) (TypeConstructor c2) = do
109 env <- getEnv
101 env <- getEnv
@@ -235,14 +227,19 @@ entails moduleName context goal@(className, ty) = do
235 , typeConstructorsAreEqual env moduleName className' (tcdClassName tcd)
227 , typeConstructorsAreEqual env moduleName className' (tcdClassName tcd)
236 , subst <- maybeToList $ typeHeadsAreEqual moduleName env ty' (tcdInstanceType tcd)
228 , subst <- maybeToList $ typeHeadsAreEqual moduleName env ty' (tcdInstanceType tcd)
237 , args <- solveSubgoals env subst (tcdDependencies tcd) ]
229 , args <- solveSubgoals env subst (tcdDependencies tcd) ]
230+ solveSubgoals :: Environment -> [(String, Type)] -> Maybe [(Qualified ProperName, Type)] -> [Maybe [Value]]
238 solveSubgoals _ _ Nothing = return Nothing
231 solveSubgoals _ _ Nothing = return Nothing
239 solveSubgoals env subst (Just subgoals) = do
232 solveSubgoals env subst (Just subgoals) = do
240 dict <- mapM (go env) (replaceAllTypeVars subst subgoals)
233 dict <- mapM (go env) (replaceAllTypeVars subst subgoals)
241 return $ Just dict
234 return $ Just dict
242− mkDictionary fnName args = maybe id (flip App) args $ (Var fnName)
235+ mkDictionary :: Qualified Ident -> Maybe [Value] -> Value
236+ mkDictionary fnName Nothing = Var fnName
237+ mkDictionary fnName (Just dicts) = foldr (flip App) (Var fnName) dicts
238+ filterModule :: TypeClassDictionaryInScope -> Bool
243 filterModule (TypeClassDictionaryInScope { tcdName = Qualified (Just mn) _ }) | mn == moduleName = True
239 filterModule (TypeClassDictionaryInScope { tcdName = Qualified (Just mn) _ }) | mn == moduleName = True
244 filterModule (TypeClassDictionaryInScope { tcdName = Qualified Nothing _ }) = True
240 filterModule (TypeClassDictionaryInScope { tcdName = Qualified Nothing _ }) = True
245 filterModule _ = False
241 filterModule _ = False
242+ canonicalizeDictionary :: TypeClassDictionaryInScope -> Qualified Ident
246 canonicalizeDictionary (TypeClassDictionaryInScope { tcdType = TCDRegular, tcdName = nm }) = nm
243 canonicalizeDictionary (TypeClassDictionaryInScope { tcdType = TCDRegular, tcdName = nm }) = nm
247 canonicalizeDictionary (TypeClassDictionaryInScope { tcdType = TCDAlias nm }) = nm
244 canonicalizeDictionary (TypeClassDictionaryInScope { tcdType = TCDAlias nm }) = nm
@@ -251,11 +248,7 @@ entails moduleName context goal@(className, ty) = do
251-- and return a substitution from type variables to types which makes the type heads unify.
248-- and return a substitution from type variables to types which makes the type heads unify.
253typeHeadsAreEqual :: ModuleName -> Environment -> Type -> Type -> Maybe [(String, Type)]
250typeHeadsAreEqual :: ModuleName -> Environment -> Type -> Type -> Maybe [(String, Type)]
254−typeHeadsAreEqual _ _ String String = Just []
255−typeHeadsAreEqual _ _ Number Number = Just []
256−typeHeadsAreEqual _ _ Boolean Boolean = Just []
257typeHeadsAreEqual _ _ (Skolem s1) (Skolem s2) | s1 == s2 = Just []
251typeHeadsAreEqual _ _ (Skolem s1) (Skolem s2) | s1 == s2 = Just []
258−typeHeadsAreEqual _ _ Array Array = Just []
259typeHeadsAreEqual m e (TypeConstructor c1) (TypeConstructor c2) | typeConstructorsAreEqual e m c1 c2 = Just []
252typeHeadsAreEqual m e (TypeConstructor c1) (TypeConstructor c2) | typeConstructorsAreEqual e m c1 c2 = Just []
260typeHeadsAreEqual m e (TypeApp h1 (TypeVar v)) (TypeApp h2 arg) = (:) (v, arg) <$> typeHeadsAreEqual m e h1 h2
253typeHeadsAreEqual m e (TypeApp h1 (TypeVar v)) (TypeApp h2 arg) = (:) (v, arg) <$> typeHeadsAreEqual m e h1 h2
261typeHeadsAreEqual m e t1@(TypeApp _ _) t2@(TypeApp _ (TypeVar _)) = typeHeadsAreEqual m e t2 t1
254typeHeadsAreEqual m e t1@(TypeApp _ _) t2@(TypeApp _ (TypeVar _)) = typeHeadsAreEqual m e t2 t1
@@ -387,13 +380,13 @@ infer val = rethrow (\e -> "Error inferring type of term " ++ prettyPrintValue v
387-- Infer a type for a value
380-- Infer a type for a value
389infer' :: Value -> UnifyT Check Value
382infer' :: Value -> UnifyT Check Value
390−infer' v@(NumericLiteral _) = return $ TypedValue True v Number
383+infer' v@(NumericLiteral _) = return $ TypedValue True v tyNumber
391−infer' v@(StringLiteral _) = return $ TypedValue True v String
384+infer' v@(StringLiteral _) = return $ TypedValue True v tyString
392−infer' v@(BooleanLiteral _) = return $ TypedValue True v Boolean
385+infer' v@(BooleanLiteral _) = return $ TypedValue True v tyBoolean
393infer' (ArrayLiteral vals) = do
386infer' (ArrayLiteral vals) = do
394 ts <- mapM infer vals
387 ts <- mapM infer vals
395 els <- fresh
388 els <- fresh
396− forM_ ts $ \(TypedValue _ _ t) -> els ?= TypeApp Array t
389+ forM_ ts $ \(TypedValue _ _ t) -> els ?= TypeApp tyArray t
397 return $ TypedValue True (ArrayLiteral ts) els
390 return $ TypedValue True (ArrayLiteral ts) els
398infer' (Unary op val) = do
391infer' (Unary op val) = do
399 v <- infer val
392 v <- infer val
@@ -418,9 +411,9 @@ infer' (ObjectUpdate o ps) = do
418 return $ TypedValue True (ObjectUpdate o' newVals) $ Object $ rowFromList (newTys, row)
411 return $ TypedValue True (ObjectUpdate o' newVals) $ Object $ rowFromList (newTys, row)
419infer' (Indexer index val) = do
412infer' (Indexer index val) = do
420 el <- fresh
413 el <- fresh
421− index' <- check index Number
414+ index' <- check index tyNumber
422− val' <- check val (TypeApp Array el)
415+ val' <- check val (TypeApp tyArray el)
423− return $ TypedValue True (Indexer (TypedValue True index' Number) (TypedValue True val' (TypeApp Array el))) el
416+ return $ TypedValue True (Indexer (TypedValue True index' tyNumber) (TypedValue True val' (TypeApp tyArray el))) el
424infer' (Accessor prop val) = do
417infer' (Accessor prop val) = do
425 typed@(TypedValue _ _ objTy) <- infer val
418 typed@(TypedValue _ _ objTy) <- infer val
426 propTy <- inferProperty objTy prop
419 propTy <- inferProperty objTy prop
@@ -431,16 +424,16 @@ infer' (Accessor prop val) = do
431 _ <- subsumes Nothing objTy (Object (RCons prop field rest))
424 _ <- subsumes Nothing objTy (Object (RCons prop field rest))
432 return $ TypedValue True (Accessor prop typed) field
425 return $ TypedValue True (Accessor prop typed) field
433 Just ty -> return $ TypedValue True (Accessor prop typed) ty
426 Just ty -> return $ TypedValue True (Accessor prop typed) ty
434−infer' (Abs args ret) = do
427+infer' (Abs arg ret) = do
435− ts <- replicateM (length args) fresh
428+ ty <- fresh
436 Just moduleName <- checkCurrentModule <$> get
429 Just moduleName <- checkCurrentModule <$> get
437− bindLocalVariables moduleName (zip args ts) $ do
430+ bindLocalVariables moduleName [(arg, ty)] $ do
438 body@(TypedValue _ _ bodyTy) <- infer' ret
431 body@(TypedValue _ _ bodyTy) <- infer' ret
439− return $ TypedValue True (Abs args body) $ Function ts bodyTy
432+ return $ TypedValue True (Abs arg body) $ function ty bodyTy
440−infer' (App f args) = do
433+infer' (App f arg) = do
441 f'@(TypedValue _ _ ft) <- infer f
434 f'@(TypedValue _ _ ft) <- infer f
442 ret <- fresh
435 ret <- fresh
443− app <- checkFunctionApplication f' ft args ret
436+ app <- checkFunctionApplication f' ft arg ret
444 return $ TypedValue True app ret
437 return $ TypedValue True app ret
445infer' (Var var) = do
438infer' (Var var) = do
446 Just moduleName <- checkCurrentModule <$> get
439 Just moduleName <- checkCurrentModule <$> get
@@ -450,7 +443,7 @@ infer' (Var var) = do
450 ConstrainedType constraints _ -> do
443 ConstrainedType constraints _ -> do
451 env <- getEnv
444 env <- getEnv
452 dicts <- getTypeClassDictionaries
445 dicts <- getTypeClassDictionaries
453− return $ TypedValue True (App (Var var) (map (flip TypeClassDictionary dicts) (qualifyAllUnqualifiedNames moduleName env constraints))) ty'
446+ return $ TypedValue True (foldl App (Var var) (map (flip TypeClassDictionary dicts) (qualifyAllUnqualifiedNames moduleName env constraints))) ty'
454 _ -> return $ TypedValue True (Var var) ty'
447 _ -> return $ TypedValue True (Var var) ty'
455infer' (Block ss) = do
448infer' (Block ss) = do
456 ret <- fresh
449 ret <- fresh
@@ -470,7 +463,7 @@ infer' (Case vals binders) = do
470 binders' <- checkBinders (map (\(TypedValue _ _ t) -> t) ts) ret binders
463 binders' <- checkBinders (map (\(TypedValue _ _ t) -> t) ts) ret binders
471 return $ TypedValue True (Case ts binders') ret
464 return $ TypedValue True (Case ts binders') ret
472infer' (IfThenElse cond th el) = do
465infer' (IfThenElse cond th el) = do
473− cond' <- check cond Boolean
466+ cond' <- check cond tyBoolean
474 v2@(TypedValue _ _ t2) <- infer th
467 v2@(TypedValue _ _ t2) <- infer th
475 v3@(TypedValue _ _ t3) <- infer el
468 v3@(TypedValue _ _ t3) <- infer el
@@ -525,9 +518,9 @@ checkUnary op val res =
525-- Built-in unary operators
518-- Built-in unary operators
527unaryOps :: [(UnaryOperator, (Type, Type))]
520unaryOps :: [(UnaryOperator, (Type, Type))]
528−unaryOps = [ (Negate, (Number, Number))
521+unaryOps = [ (Negate, (tyNumber, tyNumber))
529− , (Not, (Boolean, Boolean))
522+ , (Not, (tyBoolean, tyBoolean))
530− , (BitwiseNot, (Number, Number))
523+ , (BitwiseNot, (tyNumber, tyNumber))
@@ -536,7 +529,7 @@ unaryOps = [ (Negate, (Number, Number))
536inferBinary :: BinaryOperator -> Value -> Value -> UnifyT Check Value
529inferBinary :: BinaryOperator -> Value -> Value -> UnifyT Check Value
537inferBinary op left@(TypedValue _ _ leftTy) right@(TypedValue _ _ rightTy) | isEqualityTest op = do
530inferBinary op left@(TypedValue _ _ leftTy) right@(TypedValue _ _ rightTy) | isEqualityTest op = do
538 leftTy ?= rightTy
531 leftTy ?= rightTy
539− return $ TypedValue True (Binary op left right) Boolean
532+ return $ TypedValue True (Binary op left right) tyBoolean
540inferBinary op left@(TypedValue _ _ leftTy) right@(TypedValue _ _ rightTy) =
533inferBinary op left@(TypedValue _ _ leftTy) right@(TypedValue _ _ rightTy) =
541 case fromMaybe (error "Invalid operator") $ lookup op binaryOps of
534 case fromMaybe (error "Invalid operator") $ lookup op binaryOps of
542 (valTy, resTy) -> do
535 (valTy, resTy) -> do
@@ -550,7 +543,7 @@ inferBinary _ _ _ = error "Invalid arguments to inferBinary"
551checkBinary :: BinaryOperator -> Value -> Value -> Type -> UnifyT Check Value
544checkBinary :: BinaryOperator -> Value -> Value -> Type -> UnifyT Check Value
552checkBinary op left right res | isEqualityTest op = do
545checkBinary op left right res | isEqualityTest op = do
553− res ?= Boolean
546+ res ?= tyBoolean
554 left'@(TypedValue _ _ t1) <- infer left
547 left'@(TypedValue _ _ t1) <- infer left
555 right'@(TypedValue _ _ t2) <- infer right
548 right'@(TypedValue _ _ t2) <- infer right
@@ -575,24 +568,24 @@ isEqualityTest _ = False
575-- Built-in binary operators
568-- Built-in binary operators
577binaryOps :: [(BinaryOperator, (Type, Type))]
570binaryOps :: [(BinaryOperator, (Type, Type))]
578−binaryOps = [ (Add, (Number, Number))
571+binaryOps = [ (Add, (tyNumber, tyNumber))
579− , (Subtract, (Number, Number))
572+ , (Subtract, (tyNumber, tyNumber))
580− , (Multiply, (Number, Number))
573+ , (Multiply, (tyNumber, tyNumber))
581− , (Divide, (Number, Number))
574+ , (Divide, (tyNumber, tyNumber))
582− , (Modulus, (Number, Number))
575+ , (Modulus, (tyNumber, tyNumber))
583− , (BitwiseAnd, (Number, Number))
576+ , (BitwiseAnd, (tyNumber, tyNumber))
584− , (BitwiseOr, (Number, Number))
577+ , (BitwiseOr, (tyNumber, tyNumber))
585− , (BitwiseXor, (Number, Number))
578+ , (BitwiseXor, (tyNumber, tyNumber))
586− , (ShiftRight, (Number, Number))
579+ , (ShiftRight, (tyNumber, tyNumber))
587− , (ZeroFillShiftRight, (Number, Number))
580+ , (ZeroFillShiftRight, (tyNumber, tyNumber))
588− , (And, (Boolean, Boolean))
581+ , (And, (tyBoolean, tyBoolean))
589− , (Or, (Boolean, Boolean))
582+ , (Or, (tyBoolean, tyBoolean))
590− , (Concat, (String, String))
583+ , (Concat, (tyString, tyString))
591− , (Modulus, (Number, Number))
584+ , (Modulus, (tyNumber, tyNumber))
592− , (LessThan, (Number, Boolean))
585+ , (LessThan, (tyNumber, tyBoolean))
593− , (LessThanOrEqualTo, (Number, Boolean))
586+ , (LessThanOrEqualTo, (tyNumber, tyBoolean))
594− , (GreaterThan, (Number, Boolean))
587+ , (GreaterThan, (tyNumber, tyBoolean))
595− , (GreaterThanOrEqualTo, (Number, Boolean))
588+ , (GreaterThanOrEqualTo, (tyNumber, tyBoolean))
@@ -600,9 +593,9 @@ binaryOps = [ (Add, (Number, Number))
601inferBinder :: Type -> Binder -> UnifyT Check (M.Map Ident Type)
594inferBinder :: Type -> Binder -> UnifyT Check (M.Map Ident Type)
602inferBinder _ NullBinder = return M.empty
595inferBinder _ NullBinder = return M.empty
603−inferBinder val (StringBinder _) = val ?= String >> return M.empty
596+inferBinder val (StringBinder _) = val ?= tyString >> return M.empty
604−inferBinder val (NumberBinder _) = val ?= Number >> return M.empty
597+inferBinder val (NumberBinder _) = val ?= tyNumber >> return M.empty
605−inferBinder val (BooleanBinder _) = val ?= Boolean >> return M.empty
598+inferBinder val (BooleanBinder _) = val ?= tyBoolean >> return M.empty
606inferBinder val (VarBinder name) = return $ M.singleton name val
599inferBinder val (VarBinder name) = return $ M.singleton name val
607inferBinder val (NullaryBinder ctor) = do
600inferBinder val (NullaryBinder ctor) = do
608 env <- getEnv
601 env <- getEnv
@@ -619,7 +612,7 @@ inferBinder val (UnaryBinder ctor binder) = do
619 Just (ty, _) -> do
612 Just (ty, _) -> do
620 fn <- replaceAllVarsWithUnknowns ty
613 fn <- replaceAllVarsWithUnknowns ty
621 case fn of
614 case fn of
622− Function [obj] ret -> do
615+ TypeApp (TypeApp t obj) ret | t == tyFunction -> do
623 _ <- subsumes Nothing val ret
616 _ <- subsumes Nothing val ret
624 inferBinder obj binder
617 inferBinder obj binder
625 _ -> throwError $ "Constructor " ++ show ctor ++ " is not a unary constructor"
618 _ -> throwError $ "Constructor " ++ show ctor ++ " is not a unary constructor"
@@ -641,13 +634,13 @@ inferBinder val (ObjectBinder props) = do
641inferBinder val (ArrayBinder binders) = do
634inferBinder val (ArrayBinder binders) = do
642 el <- fresh
635 el <- fresh
643 m1 <- M.unions <$> mapM (inferBinder el) binders
636 m1 <- M.unions <$> mapM (inferBinder el) binders
644− val ?= TypeApp Array el
637+ val ?= TypeApp tyArray el
645 return m1
638 return m1
646inferBinder val (ConsBinder headBinder tailBinder) = do
639inferBinder val (ConsBinder headBinder tailBinder) = do
647 el <- fresh
640 el <- fresh
648 m1 <- inferBinder el headBinder
641 m1 <- inferBinder el headBinder
649 m2 <- inferBinder val tailBinder
642 m2 <- inferBinder val tailBinder
650− val ?= TypeApp Array el
643+ val ?= TypeApp tyArray el
651 return $ m1 `M.union` m2
644 return $ m1 `M.union` m2
652inferBinder val (NamedBinder name binder) = do
645inferBinder val (NamedBinder name binder) = do
653 m <- inferBinder val binder
646 m <- inferBinder val binder
@@ -666,7 +659,7 @@ checkBinders nvals ret ((binders, grd, val):bs) = do
666 case grd of
659 case grd of
667 Nothing -> return (binders, Nothing, val')
660 Nothing -> return (binders, Nothing, val')
668 Just g -> do
661 Just g -> do
669− g' <- check g Boolean
662+ g' <- check g tyBoolean
670 return (binders, Just g', val')
663 return (binders, Just g', val')
671 rs <- checkBinders nvals ret bs
664 rs <- checkBinders nvals ret bs
672 return $ r : rs
665 return $ r : rs
@@ -698,7 +691,7 @@ checkStatement mass _ (Assignment ident val) = do
698 Just ty -> do t ?= ty
691 Just ty -> do t ?= ty
699 return (False, mass, Assignment ident val')
692 return (False, mass, Assignment ident val')
700checkStatement mass ret (While val inner) = do
693checkStatement mass ret (While val inner) = do
701− val' <- check val Boolean
694+ val' <- check val tyBoolean
702 (allCodePathsReturn, _, inner') <- checkBlock mass ret inner
695 (allCodePathsReturn, _, inner') <- checkBlock mass ret inner
703 return (allCodePathsReturn, mass, While val' inner')
696 return (allCodePathsReturn, mass, While val' inner')
704checkStatement mass ret (If ifst) = do
697checkStatement mass ret (If ifst) = do
@@ -707,9 +700,9 @@ checkStatement mass ret (If ifst) = do
707checkStatement mass ret (For ident start end inner) = do
700checkStatement mass ret (For ident start end inner) = do
708 Just moduleName <- checkCurrentModule <$> get
701 Just moduleName <- checkCurrentModule <$> get
709 assignVariable ident
702 assignVariable ident
710− start' <- check start Number
703+ start' <- check start tyNumber
711− end' <- check end Number
704+ end' <- check end tyNumber
712− (allCodePathsReturn, _, inner') <- bindLocalVariables moduleName [(ident, Number)] $ checkBlock mass ret inner
705+ (allCodePathsReturn, _, inner') <- bindLocalVariables moduleName [(ident, tyNumber)] $ checkBlock mass ret inner
713 return (allCodePathsReturn, mass, For ident start' end' inner')
706 return (allCodePathsReturn, mass, For ident start' end' inner')
714checkStatement mass ret (Return val) = do
707checkStatement mass ret (Return val) = do
715 val' <- check val ret
708 val' <- check val ret
@@ -720,11 +713,11 @@ checkStatement mass ret (Return val) = do
721checkIfStatement :: M.Map Ident Type -> Type -> IfStatement -> UnifyT Check (Bool, IfStatement)
714checkIfStatement :: M.Map Ident Type -> Type -> IfStatement -> UnifyT Check (Bool, IfStatement)
722checkIfStatement mass ret (IfStatement val thens Nothing) = do
715checkIfStatement mass ret (IfStatement val thens Nothing) = do
723− val' <- check val Boolean
716+ val' <- check val tyBoolean
724 (_, _, thens') <- checkBlock mass ret thens
717 (_, _, thens') <- checkBlock mass ret thens
725 return (False, IfStatement val' thens' Nothing)
718 return (False, IfStatement val' thens' Nothing)
726checkIfStatement mass ret (IfStatement val thens (Just elses)) = do
719checkIfStatement mass ret (IfStatement val thens (Just elses)) = do
727− val' <- check val Boolean
720+ val' <- check val tyBoolean
728 (allCodePathsReturn1, _, thens') <- checkBlock mass ret thens
721 (allCodePathsReturn1, _, thens') <- checkBlock mass ret thens
729 (allCodePathsReturn2, elses') <- checkElseStatement mass ret elses
722 (allCodePathsReturn2, elses') <- checkElseStatement mass ret elses
730 return (allCodePathsReturn1 && allCodePathsReturn2, IfStatement val' thens' (Just elses'))
723 return (allCodePathsReturn1 && allCodePathsReturn2, IfStatement val' thens' (Just elses'))
@@ -792,31 +785,30 @@ check' val (ConstrainedType constraints ty) = do
792 TypeClassDictionaryInScope name className instanceTy Nothing TCDRegular) (map (Qualified Nothing) dictNames)
785 TypeClassDictionaryInScope name className instanceTy Nothing TCDRegular) (map (Qualified Nothing) dictNames)
793 (qualifyAllUnqualifiedNames moduleName env constraints)) $
786 (qualifyAllUnqualifiedNames moduleName env constraints)) $
794 check val ty
787 check val ty
795− return $ Abs dictNames val'
788+ return $ foldr Abs val' dictNames
796check' val u@(TUnknown _) = do
789check' val u@(TUnknown _) = do
797 val'@(TypedValue _ _ ty) <- infer val
790 val'@(TypedValue _ _ ty) <- infer val
798 -- Don't unify an unknown with an inferred polytype
791 -- Don't unify an unknown with an inferred polytype
799 ty' <- replaceAllVarsWithUnknowns ty
792 ty' <- replaceAllVarsWithUnknowns ty
801 return val'
794 return val'
802−check' v@(NumericLiteral _) Number = return v
795+check' v@(NumericLiteral _) t | t == tyNumber = return v
803−check' v@(StringLiteral _) String = return v
796+check' v@(StringLiteral _) t | t == tyString = return v
804−check' v@(BooleanLiteral _) Boolean = return v
797+check' v@(BooleanLiteral _) t | t == tyBoolean = return v
805check' (Unary op val) ty = checkUnary op val ty
798check' (Unary op val) ty = checkUnary op val ty
806check' (Binary op left right) ty = checkBinary op left right ty
799check' (Binary op left right) ty = checkBinary op left right ty
807−check' (ArrayLiteral vals) (TypeApp Array ty) = ArrayLiteral <$> forM vals (\val -> check val ty)
800+check' (ArrayLiteral vals) (TypeApp a ty) | a == tyArray = ArrayLiteral <$> forM vals (\val -> check val ty)
808check' (Indexer index vals) ty = do
801check' (Indexer index vals) ty = do
809− index' <- check index Number
802+ index' <- check index tyNumber
810− vals' <- check vals (TypeApp Array ty)
803+ vals' <- check vals (TypeApp tyArray ty)
811 return $ Indexer index' vals'
804 return $ Indexer index' vals'
812−check' (Abs args ret) (Function argTys retTy) = do
805+check' (Abs arg ret) (TypeApp (TypeApp t argTy) retTy) | t == tyFunction = do
813 Just moduleName <- checkCurrentModule <$> get
806 Just moduleName <- checkCurrentModule <$> get
814− guardWith "Incorrect number of function arguments" (length args == length argTys)
815− ret' <- bindLocalVariables moduleName (zip args argTys) $ check ret retTy
807+ ret' <- bindLocalVariables moduleName [(arg, argTy)] $ check ret retTy
816− return $ Abs args ret'
808+ return $ Abs arg ret'
817−check' (App f args) ret = do
809+check' (App f arg) ret = do
818 f'@(TypedValue _ _ ft) <- infer f
810 f'@(TypedValue _ _ ft) <- infer f
819− app <- checkFunctionApplication f' ft args ret
811+ app <- checkFunctionApplication f' ft arg ret
820 return $ app
812 return $ app
821check' v@(Var var) ty = do
813check' v@(Var var) ty = do
822 Just moduleName <- checkCurrentModule <$> get
814 Just moduleName <- checkCurrentModule <$> get
@@ -842,7 +834,7 @@ check' (Case vals binders) ret = do
842 binders' <- checkBinders ts ret binders
834 binders' <- checkBinders ts ret binders
843 return $ Case vals' binders'
835 return $ Case vals' binders'
844check' (IfThenElse cond th el) ty = do
836check' (IfThenElse cond th el) ty = do
845− cond' <- check cond Boolean
837+ cond' <- check cond tyBoolean
846 th' <- check th ty
838 th' <- check th ty
847 el' <- check el ty
839 el' <- check el ty
848 return $ IfThenElse cond' th' el'
840 return $ IfThenElse cond' th' el'
@@ -918,42 +910,44 @@ checkProperties ps row lax = let (ts, r') = rowToList row in go ps ts r' where
919-- Check the type of a function application, rethrowing errors to provide a better error message
911-- Check the type of a function application, rethrowing errors to provide a better error message
921−checkFunctionApplication :: Value -> Type -> [Value] -> Type -> UnifyT Check Value
913+checkFunctionApplication :: Value -> Type -> Value -> Type -> UnifyT Check Value
922−checkFunctionApplication fn fnTy args ret = rethrow errorMessage $ checkFunctionApplication' fn fnTy args ret
914+checkFunctionApplication fn fnTy arg ret = rethrow errorMessage $ checkFunctionApplication' fn fnTy arg ret
924 errorMessage msg = "Error applying function of type "
916 errorMessage msg = "Error applying function of type "
925 ++ prettyPrintType fnTy
917 ++ prettyPrintType fnTy
926− ++ " to arguments " ++ intercalate ", " (map prettyPrintValue args)
918+ ++ " to argument " ++ prettyPrintValue arg
927 ++ ":\n" ++ msg
919 ++ ":\n" ++ msg
930-- Check the type of a function application
922-- Check the type of a function application
932−checkFunctionApplication' :: Value -> Type -> [Value] -> Type -> UnifyT Check Value
924+checkFunctionApplication' :: Value -> Type -> Value -> Type -> UnifyT Check Value
933−checkFunctionApplication' fn (Function argTys retTy) args ret = do
925+checkFunctionApplication' fn (TypeApp (TypeApp tyFunction' argTy) retTy) arg ret = do
934− guardWith "Incorrect number of function arguments" (length args == length argTys)
926+ tyFunction' ?= tyFunction
935− args' <- zipWithM check args argTys
927+ arg' <- check arg argTy
936 _ <- subsumes Nothing retTy ret
928 _ <- subsumes Nothing retTy ret
937− return $ App fn args'
929+ return $ App fn arg'
938−checkFunctionApplication' fn (ForAll ident ty) args ret = do
930+checkFunctionApplication' fn (ForAll ident ty) arg ret = do
939 replaced <- replaceVarWithUnknown ident ty
931 replaced <- replaceVarWithUnknown ident ty
940− checkFunctionApplication fn replaced args ret
932+ checkFunctionApplication fn replaced arg ret
941−checkFunctionApplication' fn u@(TUnknown _) args ret = do
933+checkFunctionApplication' fn u@(TUnknown _) arg ret = do
935+ TypedValue _ v t <- infer arg
942− args' <- mapM (\arg -> infer arg >>= \(TypedValue _ v t) -> TypedValue True v <$> replaceAllVarsWithUnknowns t) args
936+ TypedValue True v <$> replaceAllVarsWithUnknowns t
943− let tys = map (\(TypedValue _ _ t) -> t) args'
937+ let ty = (\(TypedValue _ _ t) -> t) arg'
944− u ?= Function tys ret
938+ u ?= function ty ret
945− return $ App fn args'
939+ return $ App fn arg'
946−checkFunctionApplication' fn (SaturatedTypeSynonym name tyArgs) args ret = do
940+checkFunctionApplication' fn (SaturatedTypeSynonym name tyArgs) arg ret = do
947 ty <- expandTypeSynonym name tyArgs
941 ty <- expandTypeSynonym name tyArgs
948− checkFunctionApplication fn ty args ret
942+ checkFunctionApplication fn ty arg ret
949−checkFunctionApplication' fn (ConstrainedType constraints fnTy) args ret = do
943+checkFunctionApplication' fn (ConstrainedType constraints fnTy) arg ret = do
950 env <- getEnv
944 env <- getEnv
951 dicts <- getTypeClassDictionaries
945 dicts <- getTypeClassDictionaries
952 Just moduleName <- checkCurrentModule <$> get
946 Just moduleName <- checkCurrentModule <$> get
953− checkFunctionApplication' (App fn (map (flip TypeClassDictionary dicts) (qualifyAllUnqualifiedNames moduleName env constraints))) fnTy args ret
947+ checkFunctionApplication' (foldl App fn (map (flip TypeClassDictionary dicts) (qualifyAllUnqualifiedNames moduleName env constraints))) fnTy arg ret
954−checkFunctionApplication' _ fnTy args ret = throwError $ "Applying a function of type "
948+checkFunctionApplication' _ fnTy arg ret = throwError $ "Applying a function of type "
955 ++ prettyPrintType fnTy
949 ++ prettyPrintType fnTy
956− ++ " to argument(s) " ++ intercalate ", " (map prettyPrintValue args)
950+ ++ " to argument(s) " ++ prettyPrintValue arg
957 ++ " does not yield a value of type " ++ prettyPrintType ret ++ "."
951 ++ " does not yield a value of type " ++ prettyPrintType ret ++ "."
@@ -975,8 +969,8 @@ subsumes' :: Maybe Value -> Type -> Type -> UnifyT Check (Maybe Value)
975subsumes' val (ForAll ident ty1) ty2 = do
969subsumes' val (ForAll ident ty1) ty2 = do
976 replaced <- replaceVarWithUnknown ident ty1
970 replaced <- replaceVarWithUnknown ident ty1
977 subsumes val replaced ty2
971 subsumes val replaced ty2
978−subsumes' val (Function args1 ret1) (Function args2 ret2) = do
972+subsumes' val (TypeApp (TypeApp f1 arg1) ret1) (TypeApp (TypeApp f2 arg2) ret2) | f1 == tyFunction && f2 == tyFunction = do
979− zipWithM_ (subsumes Nothing) args2 args1
973+ subsumes Nothing arg2 arg1
980 subsumes Nothing ret1 ret2
974 subsumes Nothing ret1 ret2
981 return val
975 return val
982subsumes' (Just val) (ConstrainedType constraints ty1) ty2 = do
976subsumes' (Just val) (ConstrainedType constraints ty1) ty2 = do
@@ -984,7 +978,7 @@ subsumes' (Just val) (ConstrainedType constraints ty1) ty2 = do
984 dicts <- getTypeClassDictionaries
978 dicts <- getTypeClassDictionaries
985 Just moduleName <- checkCurrentModule <$> get
979 Just moduleName <- checkCurrentModule <$> get
986 _ <- subsumes' Nothing ty1 ty2
980 _ <- subsumes' Nothing ty1 ty2
987− return . Just $ App val (map (flip TypeClassDictionary dicts) (qualifyAllUnqualifiedNames moduleName env constraints))
981+ return . Just $ foldl App val (map (flip TypeClassDictionary dicts) (qualifyAllUnqualifiedNames moduleName env constraints))
988subsumes' val ty1 ty2 = do
982subsumes' val ty1 ty2 = do
989 ty1 ?= ty2
983 ty1 ?= ty2
990 return val
984 return val