@@ -1,25 +1,45 @@
11module Type.Constrain.Expression where
22
3−import Control.Arrow (second)
4−import Control.Applicative ((<$>))
53import qualified Data.List as List
64import qualified Data.Map as Map
7−import qualified Control.Monad as Monad
85import 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)
911
1012import SourceSyntax.Location as Loc
1113import SourceSyntax.Pattern (Pattern(PVar))
1214import SourceSyntax.Expression
15+import qualified SourceSyntax.Type as SrcT
1316import Type.Type hiding (Descriptor(..))
1417import Type.Fragment
15−import Type.Environment as Env
18+import qualified Type.Environment as Env
1619import qualified Type.Constrain.Literal as Literal
1720import qualified Type.Constrain.Pattern as Pattern
1821
19−
20−constrain :: Environment -> LExpr a b -> Type -> IO TypeConstraint
22+{-- Testing section --}
23+import SourceSyntax.PrettyPrint
24+import Parse.Expression
25+import Parse.Helpers (iParse)
26+
27+test str =
28+ case iParse expr "" str of
29+ Left err -> error $ "Parse error at " ++ show err
30+ Right expression -> do
31+ env <- Env.initialEnvironment
32+ var <- flexibleVar
33+ constraint <- constrain env expression (VarN var)
34+ prettyNames constraint
35+ print (pretty constraint)
36+ print (pretty var)
37+ return ()
38+{-- todo: remove testing code --}
39+
40+constrain :: Env.Environment -> LExpr a b -> Type -> IO TypeConstraint
2141constrain 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
2343 case expr of
2444 Literal lit -> return $ Literal.constrain env lit tipe
2545
@@ -41,7 +61,7 @@ constrain env (L _ _ expr) tipe =
4161 exists $ \t2 -> do
4262 c1 <- constrain env e1 t1
4363 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) ]
4565
4666 Lambda p e ->
4767 exists $ \t1 ->
@@ -60,7 +80,7 @@ constrain env (L _ _ expr) tipe =
6080
6181 MultiIf branches -> CAnd <$> mapM constrain' branches
6282 where
63− bool = Env.get env builtin "Bool"
83+ bool = Env.get env Env.builtin "Bool"
6484 constrain' (b,e) = do
6585 cb <- constrain env b bool
6686 ce <- constrain env e tipe
@@ -135,9 +155,8 @@ constrain env (L _ _ expr) tipe =
135155
136156
137157 Markdown _ ->
138− return $ tipe === Env.get env builtin "Element"
158+ return $ tipe === Env.get env Env.builtin "Element"
139159
140−{--
141160 Let defs body ->
142161 do c <- constrain env body tipe
143162 (schemes, rqs, fqs, header, c2, c1) <-
@@ -149,15 +168,17 @@ constrain env (L _ _ expr) tipe =
149168 (c1 /\ c))
150169
151170
152−constrainDef env info (name, qs, expr, maybeTipe) =
153− let (schemes, rigidQuantifiers, flexibleQuantifiers, headers, c2, c1) = info in
154− case maybeTipe of
155− Just tipe ->
171+constrainDef env info (pattern, expr, maybeTipe) =
172+ let qs = [] -- should come from the def, but I'm not sure what would live there...
173+ (schemes, rigidQuantifiers, flexibleQuantifiers, headers, c2, c1) = info
174+ in
175+ case (pattern, maybeTipe) of
176+ (PVar name, Just tipe) ->
156177 do flexiVars <- mapM (\_ -> flexibleVar) qs
157178 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 }
159− typ = error "This should be the internal representation of the user defined type."
160− scheme = Scheme { rigidQuantifiers = [],
179+ env' = env { Env.value = List.foldl' (\x f -> f x) (Env.value env) inserts }
180+ typ <- instantiateType tipe
181+ let scheme = Scheme { rigidQuantifiers = [],
161182 flexibleQuantifiers = flexiVars,
162183 constraint = CTrue,
163184 header = Map.singleton name typ }
@@ -169,12 +190,12 @@ constrainDef env info (name, qs, expr, maybeTipe) =
169190 , c2
170191 , fl rigidQuantifiers c /\ c1 )
171192
172− Nothing ->
193+ (PVar name, Nothing) ->
173194 do var <- flexibleVar
174195 rigidVars <- mapM (\_ -> rigidVar) qs
175196 let tipe = VarN var
176197 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 }
178199 c <- constrain env' expr tipe
179200 return ( schemes
180201 , rigidVars ++ rigidQuantifiers
@@ -183,18 +204,45 @@ constrainDef env info (name, qs, expr, maybeTipe) =
183204 , c /\ c2
184205 , c1 )
185206
186−--collapseDefs :: [Def t v] -> [(String, [String], LExpr t v, Maybe Type)]
187−collapseDefs definitions =
188− map (\(name, (expr, tipe)) -> (name, expr, tipe)) defPairs
207+instantiateType :: SrcT.Type -> IO Type
208+instantiateType sourceType = evalStateT (go sourceType) Map.empty
189209 where
190− defPairs = Map.toList (go Map.empty Map.empty definitions)
191−
192− go defs typs [] = Map.union (Map.intersectionWith (\f t -> f (Just t)) defs typs)
193− (Map.map ($ Nothing) (Map.difference defs typs))
194− go defs typs (d:ds) =
210+ go :: SrcT.Type -> StateT (Map.Map String Variable) IO Type
211+ go sourceType =
212+ case sourceType of
213+ SrcT.Lambda t1 t2 -> TermN <$> (Fun1 <$> go t1 <*> go t2)
214+
215+ SrcT.Var x -> do
216+ dict <- get
217+ case Map.lookup x dict of
218+ Just var -> return (VarN var)
219+ Nothing -> do
220+ var <- liftIO $ namedVar x -- should this be Constant or Flexible?
221+ put (Map.insert x var dict)
222+ return (VarN var)
223+
224+ SrcT.Data name ts -> do
225+ ts' <- mapM go ts
226+ return $ foldr (\t result -> TermN $ App1 t result) (error "not sure how to look this up yet") ts'
227+
228+ SrcT.EmptyRecord -> return (TermN EmptyRecord1)
229+
230+ SrcT.Record fields ext ->
231+ TermN <$> (Record1 <$> traverse (mapM go) fields <*> go ext)
232+
233+collapseDefs :: [Def t v] -> [(Pattern, LExpr t v, Maybe SrcT.Type)]
234+collapseDefs = go [] Map.empty Map.empty
235+ where
236+ go output defs typs [] =
237+ output ++ concatMap Map.elems [
238+ Map.intersectionWithKey (\k v t -> (PVar k, v, Just t)) defs typs,
239+ Map.mapWithKey (\k v -> (PVar k, v, Nothing)) (Map.difference defs typs) ]
240+ go output defs typs (d:ds) =
195241 case d of
196− Def name body ->
197− go (Map.insert name ((,) body) defs) typs ds
242+ Def (PVar name) body ->
243+ go output (Map.insert name body defs) typs ds
244+ Def pattern body ->
245+ go ((pattern, body, Nothing) : output) defs typs ds
198246 TypeAnnotation name typ ->
199− go defs (Map.insert name typ typs) ds
247+ go output defs (Map.insert name typ typs) ds
200248--}