@@ -48,19 +48,20 @@ newtype TypeSolution = TypeSolution { runTypeSolution :: (Int -> Type, Int -> Ro
48emptyTypeSolution :: TypeSolution
48emptyTypeSolution :: TypeSolution
49emptyTypeSolution = TypeSolution (TUnknown, RUnknown)
49emptyTypeSolution = TypeSolution (TUnknown, RUnknown)
51−typeOf :: String -> Value -> Check Type
51+typeOf :: String -> Value -> Check PolyType
52typeOf name val = do
52typeOf name val = do
53 me <- fresh
53 me <- fresh
54 (cs, n) <- typeConstraints (M.singleton name me) val
54 (cs, n) <- typeConstraints (M.singleton name me) val
55 solution <- solveTypeConstraints ((TypeConstraint me (TUnknown n)) : cs) emptyTypeSolution
55 solution <- solveTypeConstraints ((TypeConstraint me (TUnknown n)) : cs) emptyTypeSolution
56 return $ varIfUnknown $ fst (runTypeSolution solution) n
56 return $ varIfUnknown $ fst (runTypeSolution solution) n
58−varIfUnknown :: Type -> Type
58+varIfUnknown :: Type -> PolyType
59varIfUnknown ty =
59varIfUnknown ty =
61 (ty', m) = flip runState M.empty $ everywhereM (flip extM g $ mkM f) ty
61 (ty', m) = flip runState M.empty $ everywhereM (flip extM g $ mkM f) ty
62+ -- TODO : check no nested unknowns
63− ForAll (sort $ nub $ M.elems m) ty'
64+ PolyType (sort $ nub $ M.elems m) ty'
65 f :: Type -> State (M.Map Int String) Type
66 f :: Type -> State (M.Map Int String) Type
66 f (TUnknown n) = do
67 f (TUnknown n) = do
@@ -196,9 +197,10 @@ typeConstraints m (Var var) =
196 env <- getEnv
197 env <- getEnv
197 case M.lookup var (names env) of
198 case M.lookup var (names env) of
198 Nothing -> throwError $ var ++ " is undefined"
199 Nothing -> throwError $ var ++ " is undefined"
199− Just (ty, _) -> do
200+ Just (PolyType idents ty, _) -> do
200 me <- fresh
201 me <- fresh
202+ replaced <- replaceVarsWithUnknowns idents ty
201− return ([TypeConstraint me ty], me)
203+ return ([TypeConstraint me replaced], me)
202 Just u -> do
204 Just u -> do
203 me <- fresh
205 me <- fresh
204 return ([TypeConstraint u (TUnknown me)], me)
206 return ([TypeConstraint u (TUnknown me)], me)
@@ -209,22 +211,23 @@ typeConstraints m (Block ss) = do
209 return (cs, ret)
211 return (cs, ret)
210typeConstraints m (Constructor c) = do
212typeConstraints m (Constructor c) = do
211 env <- getEnv
213 env <- getEnv
212− case M.lookup c (names env) of
214+ case M.lookup c (dataConstructors env) of
213− Nothing -> throwError $ c ++ " is undefined"
215+ Nothing -> throwError $ "Constructor " ++ c ++ " is undefined"
214− Just (ty, _) -> do
216+ Just (PolyType idents ty) -> do
215 me <- fresh
217 me <- fresh
218+ replaced <- replaceVarsWithUnknowns idents ty
216− return ([TypeConstraint me ty], me)
219+ return ([TypeConstraint me replaced], me)
217typeConstraints m (Case val binders) = do
220typeConstraints m (Case val binders) = do
218 (cs1, n1) <- typeConstraints m val
221 (cs1, n1) <- typeConstraints m val
219 ret <- fresh
222 ret <- fresh
220 cs2 <- typeConstraintsForBinders m n1 ret binders
223 cs2 <- typeConstraintsForBinders m n1 ret binders
221 return (cs1 ++ cs2, ret)
224 return (cs1 ++ cs2, ret)
222−typeConstraints m (TypedValue val ty) = do
225+typeConstraints m (TypedValue val poly@(PolyType idents ty)) = do
223− kind <- kindOf ty
226+ kind <- kindOf poly
224 guardWith ("Expected type of kind *, was " ++ show kind) $ kind == Star
227 guardWith ("Expected type of kind *, was " ++ show kind) $ kind == Star
225− ty' <- replaceAllTypeSynonyms ty
228+ desugared <- replaceAllTypeSynonyms ty
226 (cs, n1) <- typeConstraints m val
229 (cs, n1) <- typeConstraints m val
227− return (TypeConstraint n1 ty' : cs, n1)
230+ return (TypeConstraint n1 desugared : cs, n1)
229replaceAllTypeSynonyms :: Type -> Check Type
232replaceAllTypeSynonyms :: Type -> Check Type
230replaceAllTypeSynonyms ty = do
233replaceAllTypeSynonyms ty = do
@@ -281,17 +284,17 @@ typeConstraintsForBinder val (VarBinder name) = do
281 return ([TypeConstraint me (TUnknown val)], M.singleton name me)
284 return ([TypeConstraint me (TUnknown val)], M.singleton name me)
282typeConstraintsForBinder val (NullaryBinder ctor) = do
285typeConstraintsForBinder val (NullaryBinder ctor) = do
283 env <- getEnv
286 env <- getEnv
284− case M.lookup ctor (names env) of
287+ case M.lookup ctor (dataConstructors env) of
285− Just (ForAll args ret, DataConstructor) -> do
288+ Just (PolyType args ret) -> do
286 ret' <- replaceVarsWithUnknowns args ret
289 ret' <- replaceVarsWithUnknowns args ret
287 return ([TypeConstraint val ret'], M.empty)
290 return ([TypeConstraint val ret'], M.empty)
288 _ -> throwError $ "Constructor " ++ ctor ++ " is not defined"
291 _ -> throwError $ "Constructor " ++ ctor ++ " is not defined"
289typeConstraintsForBinder val (UnaryBinder ctor binder) = do
292typeConstraintsForBinder val (UnaryBinder ctor binder) = do
290 env <- getEnv
293 env <- getEnv
291− case M.lookup ctor (names env) of
294+ case M.lookup ctor (dataConstructors env) of
292− Just (ForAll args f@(Function [_] _), DataConstructor) -> do
295+ Just (PolyType idents f@(Function [_] _)) -> do
293 obj <- fresh
296 obj <- fresh
294− (Function [ty] ret) <- replaceVarsWithUnknowns args f
297+ (Function [ty] ret) <- replaceVarsWithUnknowns idents f
295 (cs, m1) <- typeConstraintsForBinder obj binder
298 (cs, m1) <- typeConstraintsForBinder obj binder
296 return ((TypeConstraint val ret) : (TypeConstraint obj ty) : cs, m1)
299 return ((TypeConstraint val ret) : (TypeConstraint obj ty) : cs, m1)
297 Just _ -> throwError $ ctor ++ " is not a unary constructor"
300 Just _ -> throwError $ ctor ++ " is not a unary constructor"
@@ -432,8 +435,6 @@ unifyTypes (TUnknown u) t = do
432unifyTypes t (TUnknown u) = do
435unifyTypes t (TUnknown u) = do
433 typeOccursCheck u t
436 typeOccursCheck u t
434 return [TypeConstraint u t]
437 return [TypeConstraint u t]
435−unifyTypes (ForAll idents t1) t2 = join $ flip unifyTypes t2 <$> replaceVarsWithUnknowns idents t1
436−unifyTypes t1 (ForAll idents t2) = join $ unifyTypes t1 <$> replaceVarsWithUnknowns idents t2
437unifyTypes Number Number = return []
438unifyTypes Number Number = return []
438unifyTypes String String = return []
439unifyTypes String String = return []
439unifyTypes Boolean Boolean = return []
440unifyTypes Boolean Boolean = return []