@@ -1,23 +1,20 @@
2module Types.Constrain (constrain) where
2module Types.Constrain (constrain) where
4−import Data.List (foldl',sort,group,isPrefixOf,intercalate,isSuffixOf)
5−import qualified Data.Set as Set
6−import qualified Data.Map as Map
7import Control.Arrow (second)
4import Control.Arrow (second)
8import Control.Monad (liftM,mapM,zipWithM,foldM)
5import Control.Monad (liftM,mapM,zipWithM,foldM)
9import Control.Monad.State (evalState)
6import 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
12import Guid
13import Guid
14import Types.Types
15import Types.Types
15import Types.Substitutions
16import Types.Substitutions
17−--import System.IO.Unsafe
19−prints xs v = v --} unsafePerformIO (putStrLn "~~~~~~~~~~" >> mapM print xs) `seq` v
21beta = VarT `liftM` guid
18beta = VarT `liftM` guid
22unionA = Map.unionWith (++)
19unionA = Map.unionWith (++)
23unionsA = Map.unionsWith (++)
20unionsA = Map.unionsWith (++)
@@ -53,114 +50,152 @@ constrain typeHints (Module _ _ imports stmts) = do
53 allHints = Map.fromList (aliasHints ++ concat schemess)
50 allHints = Map.fromList (aliasHints ++ concat schemess)
54 assumptions <- foldM insert (unionsA ass) $ map fst (concat schemess)
51 assumptions <- foldM insert (unionsA ass) $ map fst (concat schemess)
55 findAmbiguous (map fst hints) (map fst aliasHints) assumptions $ do
52 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
57 cs = concat . Map.elems $ Map.intersectionWithKey f allHints assumptions
54 cs = concat . Map.elems $ Map.intersectionWithKey f allHints assumptions
58 escapees = Map.keys $ Map.difference assumptions allHints
55 escapees = Map.keys $ Map.difference assumptions allHints
59 return . Right . (,) escapees $ cs ++ Set.toList (Set.unions css)
56 return . Right . (,) escapees $ cs ++ Set.toList (Set.unions css)
61−gen :: Expr -> GuidCounter (Map.Map String [X],
58+type TVarMap = Map.Map String [X]
62− Set.Set (Context String Constraint),
59+type ConstraintSet = Set.Set (Context Constraint)
64−
61+ctx e span = C (Just $ show e) span
63+gen :: CExpr -> GuidCounter (TVarMap, ConstraintSet, Type)
65+ let ctx' = C (Just $ show expr) span in
66− do b <- guid
68+ do b <- guid
67− return (Map.singleton x [b], Set.empty, VarT b)
69+ return (Map.singleton x [b], Set.empty, VarT b)
69−gen e@(App e1 e2) =
71+ App e1 e2 ->
70− do (a1,c1,t1) <- gen e1
72+ do (a1,c1,t1) <- gen e1
71− (a2,c2,t2) <- gen e2
73+ (a2,c2,t2) <- gen e2
72− b <- beta
74+ b <- beta
73− return ( unionA a1 a2
75+ return ( unionA a1 a2
74− , Set.unions [c1,c2,Set.singleton . ctx e $ t1 :=: (LambdaT t2 b)]
77+ ,Set.singleton . ctx' $ t1 :=: (LambdaT t2 b)]
76−gen (Lambda x e) =
80+ Lambda x e ->
77− do (a,c,t) <- gen e
81+ do (a,c,t) <- gen e
78− b <- beta
82+ b <- beta
79− v <- guid
83+ v <- guid
80− return ( Map.delete x a
84+ return ( Map.delete x a
81− , Set.union c . Set.fromList . map (\x -> ctx e $ VarT x :=: b) $
85+ , Set.union c . Set.fromList .
86+ map (\x -> ctx' $ VarT x :=: b) $
82− Map.findWithDefault [v] x a
87+ Map.findWithDefault [v] x a
83− , LambdaT b t )
88+ , LambdaT b t )
84−gen (Let defs e) =
90+ Let defs e ->
85− do (as,cs,t) <- gen e
91+ do (as,cs,t) <- gen e
86− (ass, schemes) <- liftM unzip (mapM defScheme defs)
92+ (ass, schemes) <- liftM unzip (mapM defScheme defs)
87− let assumptions = unionsA (as:ass)
93+ let assumptions = unionsA (as:ass)
88− getName (FnDef f _ _) = f
94+ getName d = case d of FnDef f _ _ -> f
89− getName (OpDef op _ _ _) = op
95+ OpDef op _ _ _ -> op
90− names = map getName defs
96+ names = map getName defs
91− genCs name s = do
97+ genCs name s = do
92− v <- guid
98+ v <- guid
93− let vs = Map.findWithDefault [v] name assumptions
99+ let vs = Map.findWithDefault [v] name assumptions
94− return $ map (\x -> ctx (Var name) $ x :<<: s) vs
100+ return $ map (\x -> ctx name span $ x :<<: s) vs
95− cs' <- zipWithM genCs names schemes
101+ cs' <- zipWithM genCs names schemes
96− return ( foldr Map.delete assumptions names
102+ return ( foldr Map.delete assumptions names
97− , Set.union (Set.fromList . concat $ cs') cs
103+ , Set.union (Set.fromList . concat $ cs') cs
100−gen ce@(Case e cases) =
106+ Case e cases ->
101− do (as,cs,t) <- gen e
107+ do (as,cs,t) <- gen e
102− (ass,css,ts) <- liftM unzip3 $ mapM (caseGen t) cases
108+ (ass,css,ts) <- liftM unzip3 $ mapM (caseGen t) cases
103− return ( unionsA $ as:ass
109+ return ( unionsA $ as:ass
104− , let combine t1 t2 = ctx ce (t1 :=: t2) in
110+ , let cases' = map snd cases
111+ ctxs = zipWith epos cases' (tail cases')
112+ csts = zipWith (:=:) ts (tail ts)
105− Set.unions $ Set.fromList (zipWith combine ts $ tail ts) : cs : css
113+ cs' = Set.fromList (zipWith ($) ctxs csts)
114+ in Set.unions $ cs' : cs : css
106− , head ts)
115+ , head ts)
108−gen e@(If e1 e2 e3) =
117+ If e1 e2 e3 ->
109− do (a1,c1,t1) <- gen e1
118+ do (a1,c1,t1) <- gen e1
110− (a2,c2,t2) <- gen e2
119+ (a2,c2,t2) <- gen e2
111− (a3,c3,t3) <- gen e3
120+ (a3,c3,t3) <- gen e3
112− return ( unionsA [a1,a2,a3]
121+ return ( unionsA [a1,a2,a3]
113− , Set.unions [c1,c2,c3, Set.fromList [ ctx e1 (t1 :=: bool), ctx e (t2 :=: t3) ] ]
122+ , let c4 = Set.fromList [ ctx e1 span (t1 :=: bool)
123+ , ctx' (t2 :=: t3) ]
124+ in Set.unions [c1,c2,c3,c4]
116−gen (Data name es) = gen $ foldl' App (Var name) es
128+ gen $ foldl' (\f x -> epos f x $ App f x) (ctx' $ Var name) es
117−gen (Binop op e1 e2) = gen (Var op `App` e1 `App` e2)
130+ Binop op e1 e2 ->
118−
131+ gen $ ctx' (App (ctx' $ App (ctx' $ Var op) e1) e2)
119−gen (Access (Var a) b) = gen . Var $ a ++ "." ++ b
132+
120−gen (Access (Access (Var a) b) c) = gen . Var $ intercalate "." [a, b, c]
133+ Access e label ->
121−gen (Access (Access (Access (Var a) b) c) d) = gen . Var $ intercalate "." [a, b, c, d]
134+ do (as,cs,rtype) <- gen e
137+ let fs = Map.singleton label [t]
138+ c = (ctx' (RecordT fs rtype' :=: rtype))
139+ return (as, Set.insert c cs, t)
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 )
123−gen (Range e1 e2) =
151+ Range e1@(C w1 s1 _) e2@(C w2 s2 _) ->
124− do (a1,c1,t1) <- gen e1
152+ do (a1,c1,t1) <- gen e1
125− (a2,c2,t2) <- gen e2
153+ (a2,c2,t2) <- gen e2
126− return ( unionsA [a1,a2]
154+ return ( unionsA [a1,a2]
127− , Set.unions [ c1, c2, Set.fromList [ ctx e1 (t1 :=: int)
155+ , Set.unions [ c1, c2, Set.fromList [ C w1 s1 (t1 :=: int)
128− , ctx e2 (t2 :=: int) ] ]
156+ , C w1 s2 (t2 :=: int) ] ]
129− , listOf int )
157+ , listOf int )
131−gen e@(Guard ps) = do (ass,css,t:ts) <- unzip3 `liftM` mapM genPair ps
159+ MultiIf ps -> do (ass,css,t:ts) <- unzip3 `liftM` mapM genPair ps
132− let cs = Set.fromList (map (ctx e . (t :=:)) ts)
160+ let cs = Set.fromList (map (ctx' . (t :=:)) ts)
133− return (unionsA ass, Set.unions (cs:css), t)
161+ return (unionsA ass, Set.unions (cs:css), t)
134− where genPair (b,e) = do
162+ where genPair (b@(C t s _),e) = do
135− (a1,c1,t1) <- gen b
163+ (a1,c1,t1) <- gen b
136− (a2,c2,t2) <- gen e
164+ (a2,c2,t2) <- gen e
137− return ( unionsA [a1,a2]
165+ return ( unionsA [a1,a2]
166+ , Set.unions [ c1, c2
138− , Set.unions [ c1, c2, Set.singleton (ctx b (t1 :=: bool)) ]
167+ , Set.singleton (C t s (t1 :=: bool)) ]
143− IntNum _ -> do t <- beta
170+ IntNum _ -> do t <- beta
144− return (Map.empty, Set.singleton (ctx other $ t :<: number), t)
171+ return (Map.empty, Set.singleton (ctx' $ t :<: number), t)
145− FloatNum _ -> primitive float
173+ FloatNum _ -> primitive float
146− Chr _ -> primitive char
174+ Chr _ -> primitive char
147− Str _ -> primitive string
175+ Str _ -> primitive string
148− Boolean _ -> primitive bool
176+ Boolean _ -> primitive bool
149− Markdown _ -> primitive element
177+ Markdown _ -> primitive element
150 -- _ -> beta >>= primitive
178 -- _ -> beta >>= primitive
180+primitive :: Type -> GuidCounter (TVarMap, ConstraintSet, Type)
152primitive t = return (Map.empty, Set.empty, t)
181primitive t = return (Map.empty, Set.empty, t)
154−caseGen tipe (p,e) = do
183+caseGen :: Type
185+ -> GuidCounter (TVarMap, ConstraintSet, Type)
186+caseGen tipe (p, ce@(C _ span e)) = do
155− (as ,cs , t ) <- gen e
187+ (as ,cs , t ) <- gen ce
156 (as',cs',[t']) <- patternGen (as,cs,[]) p
188 (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
158 return ( as', cs'', t )
190 return ( as', cs'', t )
192+patternGen :: (TVarMap, ConstraintSet, [Type])
194+ -> GuidCounter (TVarMap, ConstraintSet, [Type])
160patternGen (as,cs,ts) PAnything = ((,,) as cs . (\t -> ts++[t])) `liftM` beta
195patternGen (as,cs,ts) PAnything = ((,,) as cs . (\t -> ts++[t])) `liftM` beta
161patternGen (as,cs,ts) (PVar v) = do
196patternGen (as,cs,ts) (PVar v) = do
162 b <- beta
197 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
164 return ( Map.delete v as, Set.union cs $ Set.fromList cs', ts ++ [b] )
199 return ( Map.delete v as, Set.union cs $ Set.fromList cs', ts ++ [b] )
165patternGen (as,cs,ts) p@(PData name ps) = do
200patternGen (as,cs,ts) p@(PData name ps) = do
166 constr <- guid
201 constr <- guid
@@ -169,11 +204,12 @@ patternGen (as,cs,ts) p@(PData name ps) = do
169 let t = foldr (==>) output ts'
204 let t = foldr (==>) output ts'
170 let getC | isTupleString name = do
205 let getC | isTupleString name = do
171 vs <- mapM (\_ -> beta) ps
206 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
173 | otherwise = return Set.empty
208 | otherwise = return Set.empty
174 cs'' <- getC
209 cs'' <- getC
175 return ( unionA as' (Map.singleton name [constr])
210 return ( unionA as' (Map.singleton name [constr])
211+ , Set.unions [cs',cs''
176− , Set.unions [cs',cs'', Set.singleton . ctx p $ VarT constr :=: t]
212+ , Set.singleton . ctx p NoSpan $ VarT constr :=: t ]
177 , ts ++ [output] )
213 , ts ++ [output] )
@@ -181,21 +217,23 @@ defScheme :: Def -> GuidCounter (Map.Map String [X], Scheme)
181defScheme def = do (as,cs,hint) <- defGen def
217defScheme def = do (as,cs,hint) <- defGen def
182 return ( as, snd hint )
218 return ( as, snd hint )
184−defGen def = case def of FnDef f args e -> defGen' f args e
220+defGen def = case def of
221+ FnDef f args e -> defGenHelp f args e
185− OpDef op a1 a2 e -> defGen' op [a1,a2] e
222+ OpDef op a1 a2 e -> defGenHelp op [a1,a2] e
186− where defGen' name args e = do
224+defGenHelp name args e = do
187− argDict <- mapM (\a -> liftM ((,) a) guid) args
225+ argDict <- mapM (\a -> liftM ((,) a) guid) args
188− (as,cs,t) <- gen e
226+ (as,cs,t) <- gen e
189− let as' = foldr Map.delete as args
227+ let as' = foldr Map.delete as args
190− tipe = foldr (==>) t $ map (VarT . snd) argDict
228+ tipe = foldr (==>) t $ map (VarT . snd) argDict
191− genCs (arg,x) = do
229+ genCs (arg,x) = do
192− v <- guid
230+ v <- guid
193− let as' = Map.findWithDefault [v] arg as
231+ let as' = Map.findWithDefault [v] arg as
194− return $ map (\y -> Context arg $ VarT x :=: VarT y) as'
232+ return $ map (\y -> ctx arg NoSpan $ VarT x :=: VarT y) as'
195− cs' <- concat `liftM` mapM genCs argDict
233+ cs' <- concat `liftM` mapM genCs argDict
196− scheme <- generalize (concat $ Map.elems as') $
234+ scheme <- generalize (concat $ Map.elems as') $
197− Forall (map snd argDict) (cs' ++ Set.toList cs) tipe
235+ Forall (map snd argDict) (cs' ++ Set.toList cs) tipe
198− return ( as', Set.empty, (name, scheme) )
236+ return ( as', Set.empty, (name, scheme) )
200stmtGen (Definition def) = do (as,cs,hint) <- defGen def
238stmtGen (Definition def) = do (as,cs,hint) <- defGen def
201 return ( as, cs, [hint] )
239 return ( as, cs, [hint] )
@@ -210,7 +248,7 @@ stmtGen (Datatype name xs tcs) = do schemes <- mapM gen' tcs'
210 | n == "Comparable" = vc
248 | n == "Comparable" = vc
211 rnm t = t
249 rnm t = t
212 tcs' = map (second (map rnm)) tcs
250 tcs' = map (second (map rnm)) tcs
213− supers t = map (Context name) $
251+ supers t = map (ctx name NoSpan) $
214 zipWith (:<:) [va,vb,vc] [number,appendable t,comparable]
252 zipWith (:<:) [va,vb,vc] [number,appendable t,comparable]
215 gen' (n,ts) = do t <- beta
253 gen' (n,ts) = do t <- beta
216 let s = Forall (xs ++ [a,b,c]) (supers t) $
254 let s = Forall (xs ++ [a,b,c]) (supers t) $
@@ -220,13 +258,13 @@ stmtGen (Datatype name xs tcs) = do schemes <- mapM gen' tcs'
220stmtGen (ExportEvent js elm tipe) = do
258stmtGen (ExportEvent js elm tipe) = do
221 x <- guid
259 x <- guid
222 return ( Map.singleton elm [x]
260 return ( Map.singleton elm [x]
223− , Set.singleton . ctx (Var elm) $ VarT x :=: tipe
261+ , Set.singleton . ctx elm NoSpan $ VarT x :=: tipe
226−stmtGen (ImportEvent js base elm tipe) = do
264+stmtGen (ImportEvent js e@(C txt span base) elm tipe) = do
227− (as,cs,t) <- gen base
265+ (as,cs,t) <- gen e
228 return ( as
266 return ( as
229− , Set.insert (ctx base (signalOf t :=: tipe)) cs
267+ , Set.insert (C txt span (signalOf t :=: tipe)) cs
230 , [ (elm, Forall [] [] tipe) ] )
268 , [ (elm, Forall [] [] tipe) ] )
232getDatatypeInfo (Datatype name args tcs) =
270getDatatypeInfo (Datatype name args tcs) =