@@ -1,25 +1,45 @@
1module Type.Constrain.Expression where
1module Type.Constrain.Expression where
3−import Control.Arrow (second)
4−import Control.Applicative ((<$>))
5import qualified Data.List as List
3import qualified Data.List as List
6import qualified Data.Map as Map
4import qualified Data.Map as Map
7−import qualified Control.Monad as Monad
8import Data.Map ((!))
5import Data.Map ((!))
6+import Control.Arrow (second)
7+import Control.Applicative ((<$>),(<*>))
8+import qualified Control.Monad as Monad
9+import Control.Monad.State
10+import Data.Traversable (traverse)
10import SourceSyntax.Location as Loc
12import SourceSyntax.Location as Loc
11import SourceSyntax.Pattern (Pattern(PVar))
13import SourceSyntax.Pattern (Pattern(PVar))
12import SourceSyntax.Expression
14import SourceSyntax.Expression
15+import qualified SourceSyntax.Type as SrcT
13import Type.Type hiding (Descriptor(..))
16import Type.Type hiding (Descriptor(..))
14import Type.Fragment
17import Type.Fragment
15−import Type.Environment as Env
18+import qualified Type.Environment as Env
16import qualified Type.Constrain.Literal as Literal
19import qualified Type.Constrain.Literal as Literal
17import qualified Type.Constrain.Pattern as Pattern
20import qualified Type.Constrain.Pattern as Pattern
19−
22+{-- Testing section --}
23+import SourceSyntax.PrettyPrint
24+import Parse.Expression
25+import Parse.Helpers (iParse)
28+ case iParse expr "" str of
29+ Left err -> error $ "Parse error at " ++ show err
30+ Right expression -> do
31+ env <- Env.initialEnvironment
33+ constraint <- constrain env expression (VarN var)
34+ prettyNames constraint
35+ print (pretty constraint)
38+{-- todo: remove testing code --}
20−constrain :: Environment -> LExpr a b -> Type -> IO TypeConstraint
40+constrain :: Env.Environment -> LExpr a b -> Type -> IO TypeConstraint
21constrain env (L _ _ expr) tipe =
41constrain env (L _ _ expr) tipe =
22− let list t = TermN (App1 (Env.get env builtin "[]") t) in
42+ let list t = TermN (App1 (Env.get env Env.builtin "[_]") t) in
23 case expr of
43 case expr of
24 Literal lit -> return $ Literal.constrain env lit tipe
44 Literal lit -> return $ Literal.constrain env lit tipe
@@ -41,7 +61,7 @@ constrain env (L _ _ expr) tipe =
41 exists $ \t2 -> do
61 exists $ \t2 -> do
42 c1 <- constrain env e1 t1
62 c1 <- constrain env e1 t1
43 c2 <- constrain env e2 t2
63 c2 <- constrain env e2 t2
44− return $ CAnd [ c1, c2, (Env.get env value op) === (t1 ==> t2 ==> tipe) ]
64+ return $ CAnd [ c1, c2, op <? (t1 ==> t2 ==> tipe) ]
46 Lambda p e ->
66 Lambda p e ->
47 exists $ \t1 ->
67 exists $ \t1 ->
@@ -60,7 +80,7 @@ constrain env (L _ _ expr) tipe =
61 MultiIf branches -> CAnd <$> mapM constrain' branches
81 MultiIf branches -> CAnd <$> mapM constrain' branches
63− bool = Env.get env builtin "Bool"
83+ bool = Env.get env Env.builtin "Bool"
64 constrain' (b,e) = do
84 constrain' (b,e) = do
65 cb <- constrain env b bool
85 cb <- constrain env b bool
66 ce <- constrain env e tipe
86 ce <- constrain env e tipe
@@ -135,9 +155,8 @@ constrain env (L _ _ expr) tipe =
137 Markdown _ ->
157 Markdown _ ->
138− return $ tipe === Env.get env builtin "Element"
158+ return $ tipe === Env.get env Env.builtin "Element"
141 Let defs body ->
160 Let defs body ->
142 do c <- constrain env body tipe
161 do c <- constrain env body tipe
143 (schemes, rqs, fqs, header, c2, c1) <-
162 (schemes, rqs, fqs, header, c2, c1) <-
@@ -149,15 +168,17 @@ constrain env (L _ _ expr) tipe =
149 (c1 /\ c))
168 (c1 /\ c))
152−constrainDef env info (name, qs, expr, maybeTipe) =
171+constrainDef env info (pattern, expr, maybeTipe) =
172+ let qs = [] -- should come from the def, but I'm not sure what would live there...
153− let (schemes, rigidQuantifiers, flexibleQuantifiers, headers, c2, c1) = info in
173+ (schemes, rigidQuantifiers, flexibleQuantifiers, headers, c2, c1) = info
154− case maybeTipe of
175+ case (pattern, maybeTipe) of
155− Just tipe ->
176+ (PVar name, Just tipe) ->
156 do flexiVars <- mapM (\_ -> flexibleVar) qs
177 do flexiVars <- mapM (\_ -> flexibleVar) qs
157 let inserts = zipWith (\arg typ -> Map.insert arg (VarN typ)) qs flexiVars
178 let inserts = zipWith (\arg typ -> Map.insert arg (VarN typ)) qs flexiVars
158− env' = env { value = List.foldl' (\x f -> f x) (value env) inserts }
179+ env' = env { Env.value = List.foldl' (\x f -> f x) (Env.value env) inserts }
159− typ = error "This should be the internal representation of the user defined type."
180+ typ <- instantiateType tipe
160− scheme = Scheme { rigidQuantifiers = [],
181+ let scheme = Scheme { rigidQuantifiers = [],
161 flexibleQuantifiers = flexiVars,
182 flexibleQuantifiers = flexiVars,
162 constraint = CTrue,
183 constraint = CTrue,
163 header = Map.singleton name typ }
184 header = Map.singleton name typ }
@@ -169,12 +190,12 @@ constrainDef env info (name, qs, expr, maybeTipe) =
170 , fl rigidQuantifiers c /\ c1 )
191 , fl rigidQuantifiers c /\ c1 )
172− Nothing ->
193+ (PVar name, Nothing) ->
173 do var <- flexibleVar
194 do var <- flexibleVar
174 rigidVars <- mapM (\_ -> rigidVar) qs
195 rigidVars <- mapM (\_ -> rigidVar) qs
175 let tipe = VarN var
196 let tipe = VarN var
176 inserts = zipWith (\arg typ -> Map.insert arg (VarN typ)) qs rigidVars
197 inserts = zipWith (\arg typ -> Map.insert arg (VarN typ)) qs rigidVars
177− env' = env { value = List.foldl' (\x f -> f x) (value env) inserts }
198+ env' = env { Env.value = List.foldl' (\x f -> f x) (Env.value env) inserts }
178 c <- constrain env' expr tipe
199 c <- constrain env' expr tipe
179 return ( schemes
200 return ( schemes
180 , rigidVars ++ rigidQuantifiers
201 , rigidVars ++ rigidQuantifiers
@@ -183,18 +204,45 @@ constrainDef env info (name, qs, expr, maybeTipe) =
183 , c /\ c2
204 , c /\ c2
186−--collapseDefs :: [Def t v] -> [(String, [String], LExpr t v, Maybe Type)]
207+instantiateType :: SrcT.Type -> IO Type
187−collapseDefs definitions =
208+instantiateType sourceType = evalStateT (go sourceType) Map.empty
188− map (\(name, (expr, tipe)) -> (name, expr, tipe)) defPairs
210+ go :: SrcT.Type -> StateT (Map.Map String Variable) IO Type
213+ SrcT.Lambda t1 t2 -> TermN <$> (Fun1 <$> go t1 <*> go t2)
217+ case Map.lookup x dict of
218+ Just var -> return (VarN var)
220+ var <- liftIO $ namedVar x -- should this be Constant or Flexible?
221+ put (Map.insert x var dict)
224+ SrcT.Data name ts -> do
226+ return $ foldr (\t result -> TermN $ App1 t result) (error "not sure how to look this up yet") ts'
228+ SrcT.EmptyRecord -> return (TermN EmptyRecord1)
230+ SrcT.Record fields ext ->
231+ TermN <$> (Record1 <$> traverse (mapM go) fields <*> go ext)
233+collapseDefs :: [Def t v] -> [(Pattern, LExpr t v, Maybe SrcT.Type)]
190− defPairs = Map.toList (go Map.empty Map.empty definitions)
234+collapseDefs = go [] Map.empty Map.empty
192− go defs typs [] = Map.union (Map.intersectionWith (\f t -> f (Just t)) defs typs)
236+ go output defs typs [] =
237+ output ++ concatMap Map.elems [
238+ Map.intersectionWithKey (\k v t -> (PVar k, v, Just t)) defs typs,
193− (Map.map ($ Nothing) (Map.difference defs typs))
239+ Map.mapWithKey (\k v -> (PVar k, v, Nothing)) (Map.difference defs typs) ]
194− go defs typs (d:ds) =
240+ go output defs typs (d:ds) =
195 case d of
241 case d of
196− Def name body ->
242+ Def (PVar name) body ->
197− go (Map.insert name ((,) body) defs) typs ds
243+ go output (Map.insert name body defs) typs ds
245+ go ((pattern, body, Nothing) : output) defs typs ds
198 TypeAnnotation name typ ->
246 TypeAnnotation name typ ->
199− go defs (Map.insert name typ typs) ds
247+ go output defs (Map.insert name typ typs) ds