@@ -48,19 +48,20 @@ newtype TypeSolution = TypeSolution { runTypeSolution :: (Int -> Type, Int -> Ro
4848emptyTypeSolution :: TypeSolution
4949emptyTypeSolution = TypeSolution (TUnknown, RUnknown)
5050
51−typeOf :: String -> Value -> Check Type
51+typeOf :: String -> Value -> Check PolyType
5252typeOf name val = do
5353 me <- fresh
5454 (cs, n) <- typeConstraints (M.singleton name me) val
5555 solution <- solveTypeConstraints ((TypeConstraint me (TUnknown n)) : cs) emptyTypeSolution
5656 return $ varIfUnknown $ fst (runTypeSolution solution) n
5757
58−varIfUnknown :: Type -> Type
58+varIfUnknown :: Type -> PolyType
5959varIfUnknown ty =
6060 let
6161 (ty', m) = flip runState M.empty $ everywhereM (flip extM g $ mkM f) ty
62+ -- TODO : check no nested unknowns
6263 in
63− ForAll (sort $ nub $ M.elems m) ty'
64+ PolyType (sort $ nub $ M.elems m) ty'
6465 where
6566 f :: Type -> State (M.Map Int String) Type
6667 f (TUnknown n) = do
@@ -196,9 +197,10 @@ typeConstraints m (Var var) =
196197 env <- getEnv
197198 case M.lookup var (names env) of
198199 Nothing -> throwError $ var ++ " is undefined"
199− Just (ty, _) -> do
200+ Just (PolyType idents ty, _) -> do
200201 me <- fresh
201− return ([TypeConstraint me ty], me)
202+ replaced <- replaceVarsWithUnknowns idents ty
203+ return ([TypeConstraint me replaced], me)
202204 Just u -> do
203205 me <- fresh
204206 return ([TypeConstraint u (TUnknown me)], me)
@@ -209,22 +211,23 @@ typeConstraints m (Block ss) = do
209211 return (cs, ret)
210212typeConstraints m (Constructor c) = do
211213 env <- getEnv
212− case M.lookup c (names env) of
213− Nothing -> throwError $ c ++ " is undefined"
214− Just (ty, _) -> do
214+ case M.lookup c (dataConstructors env) of
215+ Nothing -> throwError $ "Constructor " ++ c ++ " is undefined"
216+ Just (PolyType idents ty) -> do
215217 me <- fresh
216− return ([TypeConstraint me ty], me)
218+ replaced <- replaceVarsWithUnknowns idents ty
219+ return ([TypeConstraint me replaced], me)
217220typeConstraints m (Case val binders) = do
218221 (cs1, n1) <- typeConstraints m val
219222 ret <- fresh
220223 cs2 <- typeConstraintsForBinders m n1 ret binders
221224 return (cs1 ++ cs2, ret)
222−typeConstraints m (TypedValue val ty) = do
223− kind <- kindOf ty
225+typeConstraints m (TypedValue val poly@(PolyType idents ty)) = do
226+ kind <- kindOf poly
224227 guardWith ("Expected type of kind *, was " ++ show kind) $ kind == Star
225− ty' <- replaceAllTypeSynonyms ty
228+ desugared <- replaceAllTypeSynonyms ty
226229 (cs, n1) <- typeConstraints m val
227− return (TypeConstraint n1 ty' : cs, n1)
230+ return (TypeConstraint n1 desugared : cs, n1)
228231
229232replaceAllTypeSynonyms :: Type -> Check Type
230233replaceAllTypeSynonyms ty = do
@@ -281,17 +284,17 @@ typeConstraintsForBinder val (VarBinder name) = do
281284 return ([TypeConstraint me (TUnknown val)], M.singleton name me)
282285typeConstraintsForBinder val (NullaryBinder ctor) = do
283286 env <- getEnv
284− case M.lookup ctor (names env) of
285− Just (ForAll args ret, DataConstructor) -> do
287+ case M.lookup ctor (dataConstructors env) of
288+ Just (PolyType args ret) -> do
286289 ret' <- replaceVarsWithUnknowns args ret
287290 return ([TypeConstraint val ret'], M.empty)
288291 _ -> throwError $ "Constructor " ++ ctor ++ " is not defined"
289292typeConstraintsForBinder val (UnaryBinder ctor binder) = do
290293 env <- getEnv
291− case M.lookup ctor (names env) of
292− Just (ForAll args f@(Function [_] _), DataConstructor) -> do
294+ case M.lookup ctor (dataConstructors env) of
295+ Just (PolyType idents f@(Function [_] _)) -> do
293296 obj <- fresh
294− (Function [ty] ret) <- replaceVarsWithUnknowns args f
297+ (Function [ty] ret) <- replaceVarsWithUnknowns idents f
295298 (cs, m1) <- typeConstraintsForBinder obj binder
296299 return ((TypeConstraint val ret) : (TypeConstraint obj ty) : cs, m1)
297300 Just _ -> throwError $ ctor ++ " is not a unary constructor"
@@ -432,8 +435,6 @@ unifyTypes (TUnknown u) t = do
432435unifyTypes t (TUnknown u) = do
433436 typeOccursCheck u t
434437 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
437438unifyTypes Number Number = return []
438439unifyTypes String String = return []
439440unifyTypes Boolean Boolean = return []