@@ -1,23 +1,20 @@
11
22module Types.Constrain (constrain) where
33
4−import Data.List (foldl',sort,group,isPrefixOf,intercalate,isSuffixOf)
5−import qualified Data.Set as Set
6−import qualified Data.Map as Map
74import Control.Arrow (second)
85import Control.Monad (liftM,mapM,zipWithM,foldM)
96import Control.Monad.State (evalState)
7+import Data.List (foldl',sort,group,isPrefixOf,intercalate,isSuffixOf)
8+import qualified Data.Map as Map
9+import qualified Data.Set as Set
1010
1111import Ast
12+import Context
1213import Guid
1314
1415import Types.Types
1516import Types.Substitutions
1617
17−--import System.IO.Unsafe
18−
19−prints xs v = v --} unsafePerformIO (putStrLn "~~~~~~~~~~" >> mapM print xs) `seq` v
20−
2118beta = VarT `liftM` guid
2219unionA = Map.unionWith (++)
2320unionsA = Map.unionsWith (++)
@@ -53,114 +50,152 @@ constrain typeHints (Module _ _ imports stmts) = do
5350 allHints = Map.fromList (aliasHints ++ concat schemess)
5451 assumptions <- foldM insert (unionsA ass) $ map fst (concat schemess)
5552 findAmbiguous (map fst hints) (map fst aliasHints) assumptions $ do
56− let f k s vs = map (\v -> Context k $ v :<<: s) vs
53+ let f k s vs = map (\v -> C (Just k) NoSpan $ v :<<: s) vs
5754 cs = concat . Map.elems $ Map.intersectionWithKey f allHints assumptions
5855 escapees = Map.keys $ Map.difference assumptions allHints
5956 return . Right . (,) escapees $ cs ++ Set.toList (Set.unions css)
6057
61−gen :: Expr -> GuidCounter (Map.Map String [X],
62− Set.Set (Context String Constraint),
63− Type)
64−
65−gen (Var x) =
66− do b <- guid
67− return (Map.singleton x [b], Set.empty, VarT b)
68−
69−gen e@(App e1 e2) =
70− do (a1,c1,t1) <- gen e1
71− (a2,c2,t2) <- gen e2
72− b <- beta
73− return ( unionA a1 a2
74− , Set.unions [c1,c2,Set.singleton . ctx e $ t1 :=: (LambdaT t2 b)]
75− , b )
76−gen (Lambda x e) =
77− do (a,c,t) <- gen e
78− b <- beta
79− v <- guid
80− return ( Map.delete x a
81− , Set.union c . Set.fromList . map (\x -> ctx e $ VarT x :=: b) $
82− Map.findWithDefault [v] x a
83− , LambdaT b t )
84−gen (Let defs e) =
85− do (as,cs,t) <- gen e
86− (ass, schemes) <- liftM unzip (mapM defScheme defs)
87− let assumptions = unionsA (as:ass)
88− getName (FnDef f _ _) = f
89− getName (OpDef op _ _ _) = op
90− names = map getName defs
91− genCs name s = do
92− v <- guid
93− let vs = Map.findWithDefault [v] name assumptions
94− return $ map (\x -> ctx (Var name) $ x :<<: s) vs
95− cs' <- zipWithM genCs names schemes
96− return ( foldr Map.delete assumptions names
97− , Set.union (Set.fromList . concat $ cs') cs
98− , t )
99−
100−gen ce@(Case e cases) =
101− do (as,cs,t) <- gen e
102− (ass,css,ts) <- liftM unzip3 $ mapM (caseGen t) cases
103− return ( unionsA $ as:ass
104− , let combine t1 t2 = ctx ce (t1 :=: t2) in
105− Set.unions $ Set.fromList (zipWith combine ts $ tail ts) : cs : css
106− , head ts)
107−
108−gen e@(If e1 e2 e3) =
109− do (a1,c1,t1) <- gen e1
110− (a2,c2,t2) <- gen e2
111− (a3,c3,t3) <- gen e3
112− return ( unionsA [a1,a2,a3]
113− , Set.unions [c1,c2,c3, Set.fromList [ ctx e1 (t1 :=: bool), ctx e (t2 :=: t3) ] ]
114− , t2 )
115−
116−gen (Data name es) = gen $ foldl' App (Var name) es
117−gen (Binop op e1 e2) = gen (Var op `App` e1 `App` e2)
118−
119−gen (Access (Var a) b) = gen . Var $ a ++ "." ++ b
120−gen (Access (Access (Var a) b) c) = gen . Var $ intercalate "." [a, b, c]
121−gen (Access (Access (Access (Var a) b) c) d) = gen . Var $ intercalate "." [a, b, c, d]
122−
123−gen (Range e1 e2) =
124− do (a1,c1,t1) <- gen e1
125− (a2,c2,t2) <- gen e2
126− return ( unionsA [a1,a2]
127− , Set.unions [ c1, c2, Set.fromList [ ctx e1 (t1 :=: int)
128− , ctx e2 (t2 :=: int) ] ]
129− , listOf int )
130−
131−gen e@(Guard ps) = do (ass,css,t:ts) <- unzip3 `liftM` mapM genPair ps
132− let cs = Set.fromList (map (ctx e . (t :=:)) ts)
133− return (unionsA ass, Set.unions (cs:css), t)
134− where genPair (b,e) = do
135− (a1,c1,t1) <- gen b
136− (a2,c2,t2) <- gen e
137− return ( unionsA [a1,a2]
138− , Set.unions [ c1, c2, Set.singleton (ctx b (t1 :=: bool)) ]
139− , t2 )
140−
141−gen other =
142− case other of
143− IntNum _ -> do t <- beta
144− return (Map.empty, Set.singleton (ctx other $ t :<: number), t)
145− FloatNum _ -> primitive float
146− Chr _ -> primitive char
147− Str _ -> primitive string
148− Boolean _ -> primitive bool
149− Markdown _ -> primitive element
58+type TVarMap = Map.Map String [X]
59+type ConstraintSet = Set.Set (Context Constraint)
60+
61+ctx e span = C (Just $ show e) span
62+
63+gen :: CExpr -> GuidCounter (TVarMap, ConstraintSet, Type)
64+gen (C _ span expr) =
65+ let ctx' = C (Just $ show expr) span in
66+ case expr of
67+ Var x ->
68+ do b <- guid
69+ return (Map.singleton x [b], Set.empty, VarT b)
70+
71+ App e1 e2 ->
72+ do (a1,c1,t1) <- gen e1
73+ (a2,c2,t2) <- gen e2
74+ b <- beta
75+ return ( unionA a1 a2
76+ , Set.unions [c1,c2
77+ ,Set.singleton . ctx' $ t1 :=: (LambdaT t2 b)]
78+ , b )
79+
80+ Lambda x e ->
81+ do (a,c,t) <- gen e
82+ b <- beta
83+ v <- guid
84+ return ( Map.delete x a
85+ , Set.union c . Set.fromList .
86+ map (\x -> ctx' $ VarT x :=: b) $
87+ Map.findWithDefault [v] x a
88+ , LambdaT b t )
89+
90+ Let defs e ->
91+ do (as,cs,t) <- gen e
92+ (ass, schemes) <- liftM unzip (mapM defScheme defs)
93+ let assumptions = unionsA (as:ass)
94+ getName d = case d of FnDef f _ _ -> f
95+ OpDef op _ _ _ -> op
96+ names = map getName defs
97+ genCs name s = do
98+ v <- guid
99+ let vs = Map.findWithDefault [v] name assumptions
100+ return $ map (\x -> ctx name span $ x :<<: s) vs
101+ cs' <- zipWithM genCs names schemes
102+ return ( foldr Map.delete assumptions names
103+ , Set.union (Set.fromList . concat $ cs') cs
104+ , t )
105+
106+ Case e cases ->
107+ do (as,cs,t) <- gen e
108+ (ass,css,ts) <- liftM unzip3 $ mapM (caseGen t) cases
109+ return ( unionsA $ as:ass
110+ , let cases' = map snd cases
111+ ctxs = zipWith epos cases' (tail cases')
112+ csts = zipWith (:=:) ts (tail ts)
113+ cs' = Set.fromList (zipWith ($) ctxs csts)
114+ in Set.unions $ cs' : cs : css
115+ , head ts)
116+
117+ If e1 e2 e3 ->
118+ do (a1,c1,t1) <- gen e1
119+ (a2,c2,t2) <- gen e2
120+ (a3,c3,t3) <- gen e3
121+ return ( unionsA [a1,a2,a3]
122+ , let c4 = Set.fromList [ ctx e1 span (t1 :=: bool)
123+ , ctx' (t2 :=: t3) ]
124+ in Set.unions [c1,c2,c3,c4]
125+ , t2 )
126+
127+ Data name es ->
128+ gen $ foldl' (\f x -> epos f x $ App f x) (ctx' $ Var name) es
129+
130+ Binop op e1 e2 ->
131+ gen $ ctx' (App (ctx' $ App (ctx' $ Var op) e1) e2)
132+
133+ Access e label ->
134+ do (as,cs,rtype) <- gen e
135+ t <- beta
136+ rtype' <- beta
137+ let fs = Map.singleton label [t]
138+ c = (ctx' (RecordT fs rtype' :=: rtype))
139+ return (as, Set.insert c cs, t)
140+
141+ Record fields ->
142+ let insert label tipe = Map.insertWith (++) label [tipe]
143+ getScheme (f,args,e) = do
144+ (as, _, (label, Forall _ cs tipe)) <- defGenHelp f args e
145+ return (as, cs, insert label tipe)
146+ in do (ass, css, fs) <- unzip3 `liftM` mapM getScheme fields
147+ return ( unionsA ass
148+ , Set.fromList (concat css)
149+ , RecordT (foldr ($) Map.empty fs) EmptyRecord )
150+
151+ Range e1@(C w1 s1 _) e2@(C w2 s2 _) ->
152+ do (a1,c1,t1) <- gen e1
153+ (a2,c2,t2) <- gen e2
154+ return ( unionsA [a1,a2]
155+ , Set.unions [ c1, c2, Set.fromList [ C w1 s1 (t1 :=: int)
156+ , C w1 s2 (t2 :=: int) ] ]
157+ , listOf int )
158+
159+ MultiIf ps -> do (ass,css,t:ts) <- unzip3 `liftM` mapM genPair ps
160+ let cs = Set.fromList (map (ctx' . (t :=:)) ts)
161+ return (unionsA ass, Set.unions (cs:css), t)
162+ where genPair (b@(C t s _),e) = do
163+ (a1,c1,t1) <- gen b
164+ (a2,c2,t2) <- gen e
165+ return ( unionsA [a1,a2]
166+ , Set.unions [ c1, c2
167+ , Set.singleton (C t s (t1 :=: bool)) ]
168+ , t2 )
169+
170+ IntNum _ -> do t <- beta
171+ return (Map.empty, Set.singleton (ctx' $ t :<: number), t)
172+
173+ FloatNum _ -> primitive float
174+ Chr _ -> primitive char
175+ Str _ -> primitive string
176+ Boolean _ -> primitive bool
177+ Markdown _ -> primitive element
150178 -- _ -> beta >>= primitive
151179
180+primitive :: Type -> GuidCounter (TVarMap, ConstraintSet, Type)
152181primitive t = return (Map.empty, Set.empty, t)
153182
154−caseGen tipe (p,e) = do
155− (as ,cs , t ) <- gen e
183+caseGen :: Type
184+ -> (Pattern, CExpr)
185+ -> GuidCounter (TVarMap, ConstraintSet, Type)
186+caseGen tipe (p, ce@(C _ span e)) = do
187+ (as ,cs , t ) <- gen ce
156188 (as',cs',[t']) <- patternGen (as,cs,[]) p
157− let cs'' = Set.union cs' . Set.singleton . ctx p $ t' :=: tipe
189+ let cs'' = Set.union cs' . Set.singleton . ctx p span $ t' :=: tipe
158190 return ( as', cs'', t )
159191
192+patternGen :: (TVarMap, ConstraintSet, [Type])
193+ -> Pattern
194+ -> GuidCounter (TVarMap, ConstraintSet, [Type])
160195patternGen (as,cs,ts) PAnything = ((,,) as cs . (\t -> ts++[t])) `liftM` beta
161196patternGen (as,cs,ts) (PVar v) = do
162197 b <- beta
163− let cs' = map (\x -> ctx (Var v) $ VarT x :=: b) $ Map.findWithDefault [] v as
198+ let cs' = map (\x -> ctx v NoSpan $ VarT x :=: b) $ Map.findWithDefault [] v as
164199 return ( Map.delete v as, Set.union cs $ Set.fromList cs', ts ++ [b] )
165200patternGen (as,cs,ts) p@(PData name ps) = do
166201 constr <- guid
@@ -169,11 +204,12 @@ patternGen (as,cs,ts) p@(PData name ps) = do
169204 let t = foldr (==>) output ts'
170205 let getC | isTupleString name = do
171206 vs <- mapM (\_ -> beta) ps
172− return . Set.singleton . ctx p $ output :=: ADT name vs
207+ return . Set.singleton . C (Just $ show p) NoSpan $ output :=: ADT name vs
173208 | otherwise = return Set.empty
174209 cs'' <- getC
175210 return ( unionA as' (Map.singleton name [constr])
176− , Set.unions [cs',cs'', Set.singleton . ctx p $ VarT constr :=: t]
211+ , Set.unions [cs',cs''
212+ , Set.singleton . ctx p NoSpan $ VarT constr :=: t ]
177213 , ts ++ [output] )
178214
179215
@@ -181,21 +217,23 @@ defScheme :: Def -> GuidCounter (Map.Map String [X], Scheme)
181217defScheme def = do (as,cs,hint) <- defGen def
182218 return ( as, snd hint )
183219
184−defGen def = case def of FnDef f args e -> defGen' f args e
185− OpDef op a1 a2 e -> defGen' op [a1,a2] e
186− where defGen' name args e = do
187− argDict <- mapM (\a -> liftM ((,) a) guid) args
188− (as,cs,t) <- gen e
189− let as' = foldr Map.delete as args
190− tipe = foldr (==>) t $ map (VarT . snd) argDict
191− genCs (arg,x) = do
192− v <- guid
193− let as' = Map.findWithDefault [v] arg as
194− return $ map (\y -> Context arg $ VarT x :=: VarT y) as'
195− cs' <- concat `liftM` mapM genCs argDict
196− scheme <- generalize (concat $ Map.elems as') $
197− Forall (map snd argDict) (cs' ++ Set.toList cs) tipe
198− return ( as', Set.empty, (name, scheme) )
220+defGen def = case def of
221+ FnDef f args e -> defGenHelp f args e
222+ OpDef op a1 a2 e -> defGenHelp op [a1,a2] e
223+
224+defGenHelp name args e = do
225+ argDict <- mapM (\a -> liftM ((,) a) guid) args
226+ (as,cs,t) <- gen e
227+ let as' = foldr Map.delete as args
228+ tipe = foldr (==>) t $ map (VarT . snd) argDict
229+ genCs (arg,x) = do
230+ v <- guid
231+ let as' = Map.findWithDefault [v] arg as
232+ return $ map (\y -> ctx arg NoSpan $ VarT x :=: VarT y) as'
233+ cs' <- concat `liftM` mapM genCs argDict
234+ scheme <- generalize (concat $ Map.elems as') $
235+ Forall (map snd argDict) (cs' ++ Set.toList cs) tipe
236+ return ( as', Set.empty, (name, scheme) )
199237
200238stmtGen (Definition def) = do (as,cs,hint) <- defGen def
201239 return ( as, cs, [hint] )
@@ -210,7 +248,7 @@ stmtGen (Datatype name xs tcs) = do schemes <- mapM gen' tcs'
210248 | n == "Comparable" = vc
211249 rnm t = t
212250 tcs' = map (second (map rnm)) tcs
213− supers t = map (Context name) $
251+ supers t = map (ctx name NoSpan) $
214252 zipWith (:<:) [va,vb,vc] [number,appendable t,comparable]
215253 gen' (n,ts) = do t <- beta
216254 let s = Forall (xs ++ [a,b,c]) (supers t) $
@@ -220,13 +258,13 @@ stmtGen (Datatype name xs tcs) = do schemes <- mapM gen' tcs'
220258stmtGen (ExportEvent js elm tipe) = do
221259 x <- guid
222260 return ( Map.singleton elm [x]
223− , Set.singleton . ctx (Var elm) $ VarT x :=: tipe
261+ , Set.singleton . ctx elm NoSpan $ VarT x :=: tipe
224262 , [] )
225263
226−stmtGen (ImportEvent js base elm tipe) = do
227− (as,cs,t) <- gen base
264+stmtGen (ImportEvent js e@(C txt span base) elm tipe) = do
265+ (as,cs,t) <- gen e
228266 return ( as
229− , Set.insert (ctx base (signalOf t :=: tipe)) cs
267+ , Set.insert (C txt span (signalOf t :=: tipe)) cs
230268 , [ (elm, Forall [] [] tipe) ] )
231269
232270getDatatypeInfo (Datatype name args tcs) =