@@ -6,18 +6,21 @@ import qualified Data.Map as Map
6import qualified Type.State as TS
6import qualified Type.State as TS
7import Control.Arrow (first,second)
7import Control.Arrow (first,second)
8import Control.Monad.State
8import Control.Monad.State
9+import SourceSyntax.Location
10−unify :: Variable -> Variable -> StateT TS.SolverState IO ()
11+unify :: SrcSpan -> Variable -> Variable -> StateT TS.SolverState IO ()
11−unify variable1 variable2 = do
12+unify span variable1 variable2 = do
12 equivalent <- liftIO $ UF.equivalent variable1 variable2
13 equivalent <- liftIO $ UF.equivalent variable1 variable2
13 if equivalent then return ()
14 if equivalent then return ()
14− else actuallyUnify variable1 variable2
15+ else actuallyUnify span variable1 variable2
16−actuallyUnify :: Variable -> Variable -> StateT TS.SolverState IO ()
17+actuallyUnify :: SrcSpan -> Variable -> Variable -> StateT TS.SolverState IO ()
17−actuallyUnify variable1 variable2 = do
18+actuallyUnify span variable1 variable2 = do
18 desc1 <- liftIO $ UF.descriptor variable1
19 desc1 <- liftIO $ UF.descriptor variable1
19 desc2 <- liftIO $ UF.descriptor variable2
20 desc2 <- liftIO $ UF.descriptor variable2
21+ let unify' = unify span
20− let name' :: Maybe String
23+ name' :: Maybe String
21 name' = case (name desc1, name desc2) of
24 name' = case (name desc1, name desc2) of
22 (Just name1, Just name2) ->
25 (Just name1, Just name2) ->
23 case (flex desc1, flex desc2) of
26 case (flex desc1, flex desc2) of
@@ -69,13 +72,13 @@ actuallyUnify variable1 variable2 = do
70 flexAndUnify var = do
73 flexAndUnify var = do
71 liftIO $ UF.modifyDescriptor var $ \desc -> desc { flex = Flexible }
74 liftIO $ UF.modifyDescriptor var $ \desc -> desc { flex = Flexible }
72− unify variable1 variable2
75+ unify' variable1 variable2
74 unifyNumber svar name
77 unifyNumber svar name
75 | name `elem` ["Int","Float"] = flexAndUnify svar
78 | name `elem` ["Int","Float"] = flexAndUnify svar
76− | otherwise = TS.addError "Expecting a number (Int or Float)" variable1 variable2
79+ | otherwise = TS.addError span "Expecting a number (Int or Float)" variable1 variable2
78− comparableError str = TS.addError (str ++ msg) variable1 variable2
81+ comparableError str = TS.addError span (str ++ msg) variable1 variable2
79 where msg = "Expecting something comparable such as an\n" ++
82 where msg = "Expecting something comparable such as an\n" ++
80 "Int, Float, Char, or a list or tuple of comparables."
83 "Int, Float, Char, or a list or tuple of comparables."
@@ -88,14 +91,14 @@ actuallyUnify variable1 variable2 = do
88 case struct of
91 case struct of
89 Other -> comparableError ""
92 Other -> comparableError ""
90 List v -> do flexAndUnify varSuper
93 List v -> do flexAndUnify varSuper
91− unify v =<< liftIO (var $ Is Comparable)
94+ unify' v =<< liftIO (var $ Is Comparable)
93 | length vs > 6 ->
96 | length vs > 6 ->
94 comparableError "Cannot compare a tuple with more than 6 elements.\n"
97 comparableError "Cannot compare a tuple with more than 6 elements.\n"
95 | otherwise ->
98 | otherwise ->
96 do flexAndUnify varSuper
99 do flexAndUnify varSuper
97 cmpVars <- liftIO $ forM [1..length vs] $ \_ -> var (Is Comparable)
100 cmpVars <- liftIO $ forM [1..length vs] $ \_ -> var (Is Comparable)
98− zipWithM_ unify vs cmpVars
101+ zipWithM_ unify' vs cmpVars
100 unifyAppendable varSuper varFlex =
103 unifyAppendable varSuper varFlex =
101 do struct <- liftIO $ collectApps varFlex
104 do struct <- liftIO $ collectApps varFlex
@@ -123,15 +126,15 @@ actuallyUnify variable1 variable2 = do
123 (Is Appendable, _, _, _) -> unifyAppendable variable1 variable2
126 (Is Appendable, _, _, _) -> unifyAppendable variable1 variable2
124 (_, Is Appendable, _, _) -> unifyAppendable variable2 variable1
127 (_, Is Appendable, _, _) -> unifyAppendable variable2 variable1
126− _ -> TS.addError "" variable1 variable2
129+ _ -> TS.addError span "" variable1 variable2
128 case (structure desc1, structure desc2) of
131 case (structure desc1, structure desc2) of
129 (Nothing, Nothing) | flex desc1 == Flexible && flex desc1 == Flexible -> merge
132 (Nothing, Nothing) | flex desc1 == Flexible && flex desc1 == Flexible -> merge
130 (Nothing, _) | flex desc1 == Flexible -> merge2
133 (Nothing, _) | flex desc1 == Flexible -> merge2
131 (_, Nothing) | flex desc2 == Flexible -> merge1
134 (_, Nothing) | flex desc2 == Flexible -> merge1
133− (Just (Var1 v), _) -> unify v variable2
136+ (Just (Var1 v), _) -> unify' v variable2
134− (_, Just (Var1 v)) -> unify v variable1
137+ (_, Just (Var1 v)) -> unify' v variable1
136 (Nothing, _) -> superUnify
139 (Nothing, _) -> superUnify
137 (_, Nothing) -> superUnify
140 (_, Nothing) -> superUnify
@@ -140,35 +143,35 @@ actuallyUnify variable1 variable2 = do
140 case (type1,type2) of
143 case (type1,type2) of
141 (App1 term1 term2, App1 term1' term2') ->
144 (App1 term1 term2, App1 term1' term2') ->
143− unify term1 term1'
146+ unify' term1 term1'
144− unify term2 term2'
147+ unify' term2 term2'
145 (Fun1 term1 term2, Fun1 term1' term2') ->
148 (Fun1 term1 term2, Fun1 term1' term2') ->
147− unify term1 term1'
150+ unify' term1 term1'
148− unify term2 term2'
151+ unify' term2 term2'
150 (EmptyRecord1, EmptyRecord1) ->
153 (EmptyRecord1, EmptyRecord1) ->
151 return ()
154 return ()
153− (Record1 fields ext, EmptyRecord1) | Map.null fields -> unify ext variable2
156+ (Record1 fields ext, EmptyRecord1) | Map.null fields -> unify' ext variable2
154− (EmptyRecord1, Record1 fields ext) | Map.null fields -> unify ext variable1
157+ (EmptyRecord1, Record1 fields ext) | Map.null fields -> unify' ext variable1
156 (Record1 fields1 ext1, Record1 fields2 ext2) ->
159 (Record1 fields1 ext1, Record1 fields2 ext2) ->
157− do sequence . concat . Map.elems $ Map.intersectionWith (zipWith unify) fields1 fields2
160+ do sequence . concat . Map.elems $ Map.intersectionWith (zipWith unify') fields1 fields2
158 let mkRecord fs ext = liftIO . structuredVar $ Record1 fs ext
161 let mkRecord fs ext = liftIO . structuredVar $ Record1 fs ext
159 case (Map.null fields1', Map.null fields2') of
162 case (Map.null fields1', Map.null fields2') of
160− (True , True ) -> unify ext1 ext2
163+ (True , True ) -> unify' ext1 ext2
161 (True , False) -> do
164 (True , False) -> do
162 record2' <- mkRecord fields2' ext2
165 record2' <- mkRecord fields2' ext2
163− unify ext1 record2'
166+ unify' ext1 record2'
164 (False, True ) -> do
167 (False, True ) -> do
165 record1' <- mkRecord fields1' ext1
168 record1' <- mkRecord fields1' ext1
166− unify record1' ext2
169+ unify' record1' ext2
167 (False, False) -> do
170 (False, False) -> do
168 record1' <- mkRecord fields1' =<< liftIO (var Flexible)
171 record1' <- mkRecord fields1' =<< liftIO (var Flexible)
169 record2' <- mkRecord fields2' =<< liftIO (var Flexible)
172 record2' <- mkRecord fields2' =<< liftIO (var Flexible)
170− unify record1' ext2
173+ unify' record1' ext2
171− unify ext1 record2'
174+ unify' ext1 record2'
173 fields1' = unmerged fields1 fields2
176 fields1' = unmerged fields1 fields2
174 fields2' = unmerged fields2 fields1
177 fields2' = unmerged fields2 fields1
@@ -178,5 +181,5 @@ actuallyUnify variable1 variable2 = do
178 eat (x:xs) (y:ys) = eat xs ys
181 eat (x:xs) (y:ys) = eat xs ys
179 eat xs ys = xs
182 eat xs ys = xs
181− _ -> TS.addError "" variable1 variable2
184+ _ -> TS.addError span "" variable1 variable2