@@ -99,11 +99,8 @@ unifyTypes t1 t2 = rethrow (\e -> "Error unifying type " ++ prettyPrintType t1 +
99 unifyTypes' String String = return ()
99 unifyTypes' String String = return ()
100 unifyTypes' Boolean Boolean = return ()
100 unifyTypes' Boolean Boolean = return ()
101 unifyTypes' Array Array = return ()
101 unifyTypes' Array Array = return ()
102+ unifyTypes' Function Function = return ()
102 unifyTypes' (Object row1) (Object row2) = row1 ?= row2
103 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 ()
104 unifyTypes' (TypeVar v1) (TypeVar v2) | v1 == v2 = return ()
108 unifyTypes' (TypeConstructor c1) (TypeConstructor c2) = do
105 unifyTypes' (TypeConstructor c1) (TypeConstructor c2) = do
109 env <- getEnv
106 env <- getEnv
@@ -235,14 +232,19 @@ entails moduleName context goal@(className, ty) = do
235 , typeConstructorsAreEqual env moduleName className' (tcdClassName tcd)
232 , typeConstructorsAreEqual env moduleName className' (tcdClassName tcd)
236 , subst <- maybeToList $ typeHeadsAreEqual moduleName env ty' (tcdInstanceType tcd)
233 , subst <- maybeToList $ typeHeadsAreEqual moduleName env ty' (tcdInstanceType tcd)
237 , args <- solveSubgoals env subst (tcdDependencies tcd) ]
234 , args <- solveSubgoals env subst (tcdDependencies tcd) ]
235+ solveSubgoals :: Environment -> [(String, Type)] -> Maybe [(Qualified ProperName, Type)] -> [Maybe [Value]]
238 solveSubgoals _ _ Nothing = return Nothing
236 solveSubgoals _ _ Nothing = return Nothing
239 solveSubgoals env subst (Just subgoals) = do
237 solveSubgoals env subst (Just subgoals) = do
240 dict <- mapM (go env) (replaceAllTypeVars subst subgoals)
238 dict <- mapM (go env) (replaceAllTypeVars subst subgoals)
241 return $ Just dict
239 return $ Just dict
242− mkDictionary fnName args = maybe id (flip App) args $ (Var fnName)
240+ mkDictionary :: Qualified Ident -> Maybe [Value] -> Value
241+ mkDictionary fnName Nothing = Var fnName
242+ mkDictionary fnName (Just dicts) = foldr (flip App) (Var fnName) dicts
243+ filterModule :: TypeClassDictionaryInScope -> Bool
243 filterModule (TypeClassDictionaryInScope { tcdName = Qualified (Just mn) _ }) | mn == moduleName = True
244 filterModule (TypeClassDictionaryInScope { tcdName = Qualified (Just mn) _ }) | mn == moduleName = True
244 filterModule (TypeClassDictionaryInScope { tcdName = Qualified Nothing _ }) = True
245 filterModule (TypeClassDictionaryInScope { tcdName = Qualified Nothing _ }) = True
245 filterModule _ = False
246 filterModule _ = False
247+ canonicalizeDictionary :: TypeClassDictionaryInScope -> Qualified Ident
246 canonicalizeDictionary (TypeClassDictionaryInScope { tcdType = TCDRegular, tcdName = nm }) = nm
248 canonicalizeDictionary (TypeClassDictionaryInScope { tcdType = TCDRegular, tcdName = nm }) = nm
247 canonicalizeDictionary (TypeClassDictionaryInScope { tcdType = TCDAlias nm }) = nm
249 canonicalizeDictionary (TypeClassDictionaryInScope { tcdType = TCDAlias nm }) = nm
@@ -431,16 +433,16 @@ infer' (Accessor prop val) = do
431 _ <- subsumes Nothing objTy (Object (RCons prop field rest))
433 _ <- subsumes Nothing objTy (Object (RCons prop field rest))
432 return $ TypedValue True (Accessor prop typed) field
434 return $ TypedValue True (Accessor prop typed) field
433 Just ty -> return $ TypedValue True (Accessor prop typed) ty
435 Just ty -> return $ TypedValue True (Accessor prop typed) ty
434−infer' (Abs args ret) = do
436+infer' (Abs arg ret) = do
435− ts <- replicateM (length args) fresh
437+ ty <- fresh
436 Just moduleName <- checkCurrentModule <$> get
438 Just moduleName <- checkCurrentModule <$> get
437− bindLocalVariables moduleName (zip args ts) $ do
439+ bindLocalVariables moduleName [(arg, ty)] $ do
438 body@(TypedValue _ _ bodyTy) <- infer' ret
440 body@(TypedValue _ _ bodyTy) <- infer' ret
439− return $ TypedValue True (Abs args body) $ Function ts bodyTy
441+ return $ TypedValue True (Abs arg body) $ function ty bodyTy
440−infer' (App f args) = do
442+infer' (App f arg) = do
441 f'@(TypedValue _ _ ft) <- infer f
443 f'@(TypedValue _ _ ft) <- infer f
442 ret <- fresh
444 ret <- fresh
443− app <- checkFunctionApplication f' ft args ret
445+ app <- checkFunctionApplication f' ft arg ret
444 return $ TypedValue True app ret
446 return $ TypedValue True app ret
445infer' (Var var) = do
447infer' (Var var) = do
446 Just moduleName <- checkCurrentModule <$> get
448 Just moduleName <- checkCurrentModule <$> get
@@ -450,7 +452,7 @@ infer' (Var var) = do
450 ConstrainedType constraints _ -> do
452 ConstrainedType constraints _ -> do
451 env <- getEnv
453 env <- getEnv
452 dicts <- getTypeClassDictionaries
454 dicts <- getTypeClassDictionaries
453− return $ TypedValue True (App (Var var) (map (flip TypeClassDictionary dicts) (qualifyAllUnqualifiedNames moduleName env constraints))) ty'
455+ return $ TypedValue True (foldr App (Var var) (map (flip TypeClassDictionary dicts) (qualifyAllUnqualifiedNames moduleName env constraints))) ty'
454 _ -> return $ TypedValue True (Var var) ty'
456 _ -> return $ TypedValue True (Var var) ty'
455infer' (Block ss) = do
457infer' (Block ss) = do
456 ret <- fresh
458 ret <- fresh
@@ -619,7 +621,7 @@ inferBinder val (UnaryBinder ctor binder) = do
619 Just (ty, _) -> do
621 Just (ty, _) -> do
620 fn <- replaceAllVarsWithUnknowns ty
622 fn <- replaceAllVarsWithUnknowns ty
621 case fn of
623 case fn of
622− Function [obj] ret -> do
624+ TypeApp (TypeApp Function obj) ret -> do
623 _ <- subsumes Nothing val ret
625 _ <- subsumes Nothing val ret
624 inferBinder obj binder
626 inferBinder obj binder
625 _ -> throwError $ "Constructor " ++ show ctor ++ " is not a unary constructor"
627 _ -> throwError $ "Constructor " ++ show ctor ++ " is not a unary constructor"
@@ -792,7 +794,7 @@ check' val (ConstrainedType constraints ty) = do
792 TypeClassDictionaryInScope name className instanceTy Nothing TCDRegular) (map (Qualified Nothing) dictNames)
794 TypeClassDictionaryInScope name className instanceTy Nothing TCDRegular) (map (Qualified Nothing) dictNames)
793 (qualifyAllUnqualifiedNames moduleName env constraints)) $
795 (qualifyAllUnqualifiedNames moduleName env constraints)) $
794 check val ty
796 check val ty
795− return $ Abs dictNames val'
797+ return $ foldr Abs val' dictNames
796check' val u@(TUnknown _) = do
798check' val u@(TUnknown _) = do
797 val'@(TypedValue _ _ ty) <- infer val
799 val'@(TypedValue _ _ ty) <- infer val
798 -- Don't unify an unknown with an inferred polytype
800 -- Don't unify an unknown with an inferred polytype
@@ -809,14 +811,13 @@ check' (Indexer index vals) ty = do
809 index' <- check index Number
811 index' <- check index Number
810 vals' <- check vals (TypeApp Array ty)
812 vals' <- check vals (TypeApp Array ty)
811 return $ Indexer index' vals'
813 return $ Indexer index' vals'
812−check' (Abs args ret) (Function argTys retTy) = do
814+check' (Abs arg ret) (TypeApp (TypeApp Function argTy) retTy) = do
813 Just moduleName <- checkCurrentModule <$> get
815 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
816+ ret' <- bindLocalVariables moduleName [(arg, argTy)] $ check ret retTy
816− return $ Abs args ret'
817+ return $ Abs arg ret'
817−check' (App f args) ret = do
818+check' (App f arg) ret = do
818 f'@(TypedValue _ _ ft) <- infer f
819 f'@(TypedValue _ _ ft) <- infer f
819− app <- checkFunctionApplication f' ft args ret
820+ app <- checkFunctionApplication f' ft arg ret
820 return $ app
821 return $ app
821check' v@(Var var) ty = do
822check' v@(Var var) ty = do
822 Just moduleName <- checkCurrentModule <$> get
823 Just moduleName <- checkCurrentModule <$> get
@@ -918,42 +919,43 @@ 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
920-- Check the type of a function application, rethrowing errors to provide a better error message
921−checkFunctionApplication :: Value -> Type -> [Value] -> Type -> UnifyT Check Value
922+checkFunctionApplication :: Value -> Type -> Value -> Type -> UnifyT Check Value
922−checkFunctionApplication fn fnTy args ret = rethrow errorMessage $ checkFunctionApplication' fn fnTy args ret
923+checkFunctionApplication fn fnTy arg ret = rethrow errorMessage $ checkFunctionApplication' fn fnTy arg ret
924 errorMessage msg = "Error applying function of type "
925 errorMessage msg = "Error applying function of type "
925 ++ prettyPrintType fnTy
926 ++ prettyPrintType fnTy
926− ++ " to arguments " ++ intercalate ", " (map prettyPrintValue args)
927+ ++ " to argument " ++ prettyPrintValue arg
927 ++ ":\n" ++ msg
928 ++ ":\n" ++ msg
930-- Check the type of a function application
931-- Check the type of a function application
932−checkFunctionApplication' :: Value -> Type -> [Value] -> Type -> UnifyT Check Value
933+checkFunctionApplication' :: Value -> Type -> Value -> Type -> UnifyT Check Value
933−checkFunctionApplication' fn (Function argTys retTy) args ret = do
934+checkFunctionApplication' fn (TypeApp (TypeApp Function argTy) retTy) arg ret = do
934− guardWith "Incorrect number of function arguments" (length args == length argTys)
935+ arg' <- check arg argTy
935− args' <- zipWithM check args argTys
936 _ <- subsumes Nothing retTy ret
936 _ <- subsumes Nothing retTy ret
937− return $ App fn args'
937+ return $ App fn arg'
938−checkFunctionApplication' fn (ForAll ident ty) args ret = do
938+checkFunctionApplication' fn (ForAll ident ty) arg ret = do
939 replaced <- replaceVarWithUnknown ident ty
939 replaced <- replaceVarWithUnknown ident ty
940− checkFunctionApplication fn replaced args ret
940+ checkFunctionApplication fn replaced arg ret
941−checkFunctionApplication' fn u@(TUnknown _) args ret = do
941+checkFunctionApplication' fn u@(TUnknown _) arg ret = do
943+ TypedValue _ v t <- infer arg
942− args' <- mapM (\arg -> infer arg >>= \(TypedValue _ v t) -> TypedValue True v <$> replaceAllVarsWithUnknowns t) args
944+ TypedValue True v <$> replaceAllVarsWithUnknowns t
943− let tys = map (\(TypedValue _ _ t) -> t) args'
945+ let ty = (\(TypedValue _ _ t) -> t) arg'
944− u ?= Function tys ret
946+ u ?= function ty ret
945− return $ App fn args'
947+ return $ App fn arg'
946−checkFunctionApplication' fn (SaturatedTypeSynonym name tyArgs) args ret = do
948+checkFunctionApplication' fn (SaturatedTypeSynonym name tyArgs) arg ret = do
947 ty <- expandTypeSynonym name tyArgs
949 ty <- expandTypeSynonym name tyArgs
948− checkFunctionApplication fn ty args ret
950+ checkFunctionApplication fn ty arg ret
949−checkFunctionApplication' fn (ConstrainedType constraints fnTy) args ret = do
951+checkFunctionApplication' fn (ConstrainedType constraints fnTy) arg ret = do
950 env <- getEnv
952 env <- getEnv
951 dicts <- getTypeClassDictionaries
953 dicts <- getTypeClassDictionaries
952 Just moduleName <- checkCurrentModule <$> get
954 Just moduleName <- checkCurrentModule <$> get
953− checkFunctionApplication' (App fn (map (flip TypeClassDictionary dicts) (qualifyAllUnqualifiedNames moduleName env constraints))) fnTy args ret
955+ checkFunctionApplication' (foldr App fn (map (flip TypeClassDictionary dicts) (qualifyAllUnqualifiedNames moduleName env constraints))) fnTy arg ret
954−checkFunctionApplication' _ fnTy args ret = throwError $ "Applying a function of type "
956+checkFunctionApplication' _ fnTy arg ret = throwError $ "Applying a function of type "
955 ++ prettyPrintType fnTy
957 ++ prettyPrintType fnTy
956− ++ " to argument(s) " ++ intercalate ", " (map prettyPrintValue args)
958+ ++ " to argument(s) " ++ prettyPrintValue arg
957 ++ " does not yield a value of type " ++ prettyPrintType ret ++ "."
959 ++ " does not yield a value of type " ++ prettyPrintType ret ++ "."
@@ -975,8 +977,8 @@ subsumes' :: Maybe Value -> Type -> Type -> UnifyT Check (Maybe Value)
975subsumes' val (ForAll ident ty1) ty2 = do
977subsumes' val (ForAll ident ty1) ty2 = do
976 replaced <- replaceVarWithUnknown ident ty1
978 replaced <- replaceVarWithUnknown ident ty1
977 subsumes val replaced ty2
979 subsumes val replaced ty2
978−subsumes' val (Function args1 ret1) (Function args2 ret2) = do
980+subsumes' val (TypeApp (TypeApp Function arg1) ret1) (TypeApp (TypeApp Function arg2) ret2) = do
979− zipWithM_ (subsumes Nothing) args2 args1
981+ subsumes Nothing arg2 arg1
980 subsumes Nothing ret1 ret2
982 subsumes Nothing ret1 ret2
981 return val
983 return val
982subsumes' (Just val) (ConstrainedType constraints ty1) ty2 = do
984subsumes' (Just val) (ConstrainedType constraints ty1) ty2 = do
@@ -984,7 +986,7 @@ subsumes' (Just val) (ConstrainedType constraints ty1) ty2 = do
984 dicts <- getTypeClassDictionaries
986 dicts <- getTypeClassDictionaries
985 Just moduleName <- checkCurrentModule <$> get
987 Just moduleName <- checkCurrentModule <$> get
986 _ <- subsumes' Nothing ty1 ty2
988 _ <- subsumes' Nothing ty1 ty2
987− return . Just $ App val (map (flip TypeClassDictionary dicts) (qualifyAllUnqualifiedNames moduleName env constraints))
989+ return . Just $ foldr App val (map (flip TypeClassDictionary dicts) (qualifyAllUnqualifiedNames moduleName env constraints))
988subsumes' val ty1 ty2 = do
990subsumes' val ty1 ty2 = do
989 ty1 ?= ty2
991 ty1 ?= ty2
990 return val
992 return val