@@ -48,7 +48,7 @@ constrain env (L _ _ expr) tipe =
48 exists $ \t2 -> do
48 exists $ \t2 -> do
49 fragment <- Pattern.constrain env p t1
49 fragment <- Pattern.constrain env p t1
50 c2 <- constrain env e t2
50 c2 <- constrain env e t2
51− let c = ex (vars fragment) (CLet [Scheme [] [] CTrue (typeEnv fragment)]
51+ let c = ex (vars fragment) (CLet [monoscheme (typeEnv fragment)]
52 (typeConstraint fragment /\ c2 ))
52 (typeConstraint fragment /\ c2 ))
53 return $ c /\ tipe === (t1 ==> t2)
53 return $ c /\ tipe === (t1 ==> t2)
@@ -66,8 +66,6 @@ constrain env (L _ _ expr) tipe =
66 ce <- constrain env e tipe
66 ce <- constrain env e tipe
67 return (cb /\ ce)
67 return (cb /\ ce)
69− Let defs body -> error "not defined yet"
71 Case e branches ->
69 Case e branches ->
72 exists $ \t -> do
70 exists $ \t -> do
73 ce <- constrain env e t
71 ce <- constrain env e t
@@ -75,7 +73,7 @@ constrain env (L _ _ expr) tipe =
75 fragment <- Pattern.constrain env p t
73 fragment <- Pattern.constrain env p t
76 c <- constrain env e tipe
74 c <- constrain env e tipe
77 return $ ex (vars fragment)
75 return $ ex (vars fragment)
78− (CLet [Scheme [] [] CTrue (typeEnv fragment)]
76+ (CLet [monoscheme (typeEnv fragment)]
79 (typeConstraint fragment /\ c))
77 (typeConstraint fragment /\ c))
80 CAnd . (:) ce <$> mapM branch branches
78 CAnd . (:) ce <$> mapM branch branches
@@ -140,16 +138,62 @@ constrain env (L _ _ expr) tipe =
140 Markdown _ ->
138 Markdown _ ->
141 return $ tipe === Env.get env builtin "Element"
139 return $ tipe === Env.get env builtin "Element"
142+ do c <- constrain env body tipe
143+ (schemes, rqs, fqs, header, c2, c1) <-
144+ Monad.foldM (constrainDef env)
145+ ([], [], [], Map.empty, CTrue, CTrue)
147+ return $ CLet schemes
148+ (CLet [Scheme rqs fqs (CLet [monoscheme header] c2) header ]
152+constrainDef env info (name, args, expr, maybeTipe) =
153+ let (schemes, rigidQuantifiers, flexibleQuantifiers, headers, c2, c1) = info in
156+ do flexiVars <- mapM (\_ -> flexibleVar) args
157+ let inserts = zipWith (\arg typ -> Map.insert arg (VarN typ)) args flexiVars
158+ env' = env { value = List.foldl' (\x f -> f x) (value env) inserts }
159+ typ = error "This should be the internal representation of the user defined type."
160+ scheme = Scheme { rigidQuantifiers = [],
161+ flexibleQuantifiers = flexiVars,
163+ header = Map.singleton name typ }
164+ c <- constrain env' expr typ
165+ return ( scheme : schemes
167+ , flexibleQuantifiers
170+ , fl rigidQuantifiers c /\ c1 )
173+ do var <- flexibleVar
174+ rigidVars <- mapM (\_ -> rigidVar) args
176+ inserts = zipWith (\arg typ -> Map.insert arg (VarN typ)) args rigidVars
177+ env' = env { value = List.foldl' (\x f -> f x) (value env) inserts }
178+ c <- constrain env' expr tipe
180+ , rigidVars ++ rigidQuantifiers
181+ , var : flexibleQuantifiers
182+ , Map.insert name tipe headers
144--collapseDefs :: [Def t v] -> [(String, [String], LExpr t v, Maybe Type)]
186--collapseDefs :: [Def t v] -> [(String, [String], LExpr t v, Maybe Type)]
145−collapseDefs = go Map.empty Map.empty
187+collapseDefs definitions =
188+ map (\(name, (args, expr, tipe)) -> (name, args, expr, tipe)) defPairs
190+ defPairs = Map.toList (go Map.empty Map.empty definitions)
147− go defs typs [] = Map.union (Map.intersectionWith (\f t -> f (Just t)) defs typs)
192+ go defs typs [] = Map.union (Map.intersectionWith (\f t -> f (Just t)) defs typs)
148− (Map.map ($ Nothing) (Map.difference defs typs))
193+ (Map.map ($ Nothing) (Map.difference defs typs))
149− go defs typs (d:ds) =
194+ go defs typs (d:ds) =
150− case d of
195+ case d of
151− Def name args body ->
196+ Def name args body ->
152− go (Map.insert name ((,,) args body) defs) typs ds
197+ go (Map.insert name ((,,) args body) defs) typs ds
153− TypeAnnotation name typ ->
198+ TypeAnnotation name typ ->
154− go defs (Map.insert name typ typs) ds
199+ go defs (Map.insert name typ typs) ds