@@ -13,14 +13,17 @@ import Guid
1313import Types.Types
1414import Types.Constrain
1515import Types.Substitutions
16+import Types.Alias (dealias)
1617
1718isSolved ss (C _ _ (t1 :=: t2)) = t1 == t2
1819isSolved ss (C _ _ (x :<<: _)) = isJust (lookup x ss)
1920isSolved ss c = False
2021
21−crush :: Scheme -> GuidCounter (Either String Scheme)
22−crush (Forall xs cs t) =
23− do subs <- solver cs Map.empty
22+type Aliases = Map.Map String ([X],Type)
23+
24+crush :: Aliases -> Scheme -> GuidCounter (Either String Scheme)
25+crush aliases (Forall xs cs t) =
26+ do subs <- solver aliases Map.empty cs
2427 return $ do ss' <- subs
2528 let ss = Map.toList ss'
2629 cs' = filter (not . isSolved ss) (subst ss cs)
@@ -34,10 +37,11 @@ schemeSubHelp txt span x s t1 rltn t2 = do
3437 | otherwise = do (st, cs) <- concretize s
3538 return (subst [(x,st)] t, cs)
3639
37−schemeSub x s c = do s' <- crush s
38− case s' of
39− Right s'' -> Right `liftM` schemeSub' x s'' c
40− Left err -> return $ Left err
40+schemeSub aliases x s c =
41+ do s' <- crush aliases s
42+ case s' of
43+ Right s'' -> Right `liftM` schemeSub' x s'' c
44+ Left err -> return $ Left err
4145
4246schemeSub' x s c@(C txt span constraint) =
4347 case constraint of
@@ -77,29 +81,34 @@ recordConstraints eq fs t fs' t' =
7781 let tipe = RecordT (Map.singleton k bs) (VarT x)
7882 return (cs ++ [eq t tipe])
7983
80−solver :: [Context Constraint]
84+solver :: Aliases
8185 -> Map.Map X Type
86+ -> [Context Constraint]
8287 -> GuidCounter (Either String (Map.Map X Type))
83−solver [] subs = return $ Right subs
84−solver (C txt span c : cs) subs =
88+solver _ subs [] = return $ Right subs
89+solver aliases subs (C txt span c : cs) =
8590 let ctx = C txt span
8691 eq t1 t2 = ctx (t1 :=: t2)
92+ solv = solver aliases subs
8793 in case c of
8894 -- Destruct Type-constructors
8995 t1@(ADT n1 ts1) :=: t2@(ADT n2 ts2) ->
90− if n1 /= n2 then uniError txt span t1 t2 else
91− solver (zipWith eq ts1 ts2 ++ cs) subs
96+ if n1 == n2 then solv (zipWith eq ts1 ts2 ++ cs)
97+ else let t1' = dealias aliases t1
98+ t2' = dealias aliases t2
99+ in if t1 == t1' && t2 == t2' then uniError txt span t1 t2
100+ else solv (ctx (t1' :=: t2') : cs)
92101
93102 LambdaT t1 t2 :=: LambdaT t1' t2' ->
94− solver ([ eq t1 t1', eq t2 t2' ] ++ cs) subs
103+ solv ([ eq t1 t1', eq t2 t2' ] ++ cs)
95104
96105 RecordT fs t :=: RecordT fs' t' ->
97106 do cs' <- recordConstraints eq fs t fs' t'
98− solver (cs' ++ cs) subs
107+ solv (cs' ++ cs)
99108
100109 -- Type-equality
101110 VarT x :=: VarT y
102− | x == y -> solver cs subs
111+ | x == y -> solv cs
103112 | otherwise ->
104113 case (Map.lookup x subs, Map.lookup y subs) of
105114 (Just (Super xts), Just (Super yts)) ->
@@ -108,68 +117,68 @@ solver (C txt span c : cs) subs =
108117 in case Set.toList ts of
109118 [] -> unionError txt span xts yts
110119 [t] -> let cs1 = subst [(x,t),(y,t)] cs in
111− cs1 `seq` solver cs1 (setXY t subs)
112− _ -> solver cs $ setXY (Super ts) subs
120+ cs1 `seq` solver aliases (setXY t subs) cs1
121+ _ -> solver aliases (setXY (Super ts) subs) cs
113122 (Just (Super xts), _) ->
114123 let cs2 = subst [(y,VarT x)] cs in
115− solver cs2 $ Map.insert y (VarT x) subs
124+ solver aliases (Map.insert y (VarT x) subs) cs2
116125 (_, _) ->
117126 let cs3 = subst [(x,VarT y)] cs in
118− solver cs3 $ Map.insert x (VarT y) subs
127+ solver aliases (Map.insert x (VarT y) subs) cs3
119128
120129 VarT x :=: t -> do
121130 if x `occurs` t then occursError txt span (VarT x) t else
122131 (case Map.lookup x subs of
123− Nothing -> let cs4 = subst [(x,t)] cs in
124− solver cs4 . Map.map (subst [(x,t)]) $
125− Map.insert x t subs
132+ Nothing ->
133+ let cs4 = subst [(x,t)] cs
134+ subs' = Map.map (subst [(x,t)]) $ Map.insert x t subs
135+ in solver aliases subs' cs4
126136 Just (Super ts) ->
127137 let ts' = Set.intersection ts (Set.singleton t) in
128138 case Set.toList ts' of
129− [] -> solver (ctx (t :<: Super ts) : cs) subs
139+ [] -> solv (ctx (t :<: Super ts) : cs)
130140 [t'] -> let cs5 = subst [(x,t)] cs in
131− solver cs5 $ Map.insert x t' subs
132− _ -> solver cs $ Map.insert x (Super ts') subs
133− Just t' -> solver (ctx (t' :=: t) : cs) subs
141+ solver aliases (Map.insert x t' subs) cs5
142+ _ -> solver aliases (Map.insert x (Super ts') subs) cs
143+ Just t' -> solv (ctx (t' :=: t) : cs)
134144 )
135145
136− t :=: VarT x -> solver ((ctx (VarT x :=: t)) : cs) subs
146+ t :=: VarT x -> solv ((ctx (VarT x :=: t)) : cs)
137147
138− t1 :=: t2 | t1 == t2 -> solver cs subs
148+ t1 :=: t2 | t1 == t2 -> solv cs
139149 | otherwise -> uniError txt span t1 t2
140150
141151 -- subtypes
142152 VarT x :<: Super ts ->
143153 case Map.lookup x subs of
144− Nothing -> solver cs $ Map.insert x (Super ts) subs
154+ Nothing -> solver aliases (Map.insert x (Super ts) subs) cs
145155 Just (Super ts') ->
146156 case Set.toList $ Set.intersection ts ts' of
147157 [] -> unionError txt span ts ts'
148− [t] -> solver (subst [(x,t)] cs) $ Map.insert x t subs
149− ts'' -> solver cs $
150− Map.insert x (Super $ Set.fromList ts'') subs
158+ [t] -> solver aliases (Map.insert x t subs) (subst [(x,t)] cs)
159+ ts'' -> solver aliases subs' cs
160+ where subs' = Map.insert x (Super $ Set.fromList ts'') subs
151161
152162 ADT "List" [t] :<: Super ts
153− | any f (Set.toList ts) -> solver cs subs
163+ | any f (Set.toList ts) -> solv cs
154164 | otherwise -> subtypeError txt span (ADT "List" [t]) (Super ts)
155165 where f (ADT "List" [VarT _]) = True
156166 f (ADT "List" [t']) = t == t'
157167 f _ = False
158168
159169 t :<: Super ts
160− | Set.member t ts -> solver cs subs
170+ | Set.member t ts -> solv cs
161171 | otherwise -> subtypeError txt span t (Super ts)
162172
163173 x :<<: s
164174 | any (occurs x) cs ->
165− do css <- mapM (schemeSub x s) cs
175+ do css <- mapM (schemeSub aliases x s) cs
166176 case lefts css of
167177 err : _ -> return $ Left err
168− [] -> solver (concat (rights css)) subs
178+ [] -> solv (concat (rights css))
169179 | otherwise ->
170180 do (t,cs7) <- concretize s
171− let cs'' = (cs ++ ctx (VarT x :=: t) : cs7)
172− solver cs'' subs
181+ solv (cs ++ ctx (VarT x :=: t) : cs7)
173182
174183showMsg msg = case msg of
175184 Just str -> "\nIn context: " ++ str