@@ -3,12 +3,10 @@
3module Type.Unify
3module Type.Unify
4 ( Answer(..)
4 ( Answer(..)
11−import Control.Monad (foldM, liftM2, zipWithM_)
12import qualified Data.Map.Strict as Map
10import qualified Data.Map.Strict as Map
14import qualified AST.Canonical as Can
12import qualified AST.Canonical as Can
@@ -25,18 +23,18 @@ import qualified Type.UnionFind as UF
26data Answer
24data Answer
27 = Ok [Variable]
25 = Ok [Variable]
28− | Err [Variable] Problem Can.Type Can.Type
26+ | Err [Variable] Can.Type Can.Type
31unify :: Variable -> Variable -> IO Answer
29unify :: Variable -> Variable -> IO Answer
32unify v1 v2 =
30unify v1 v2 =
33− case guardedUnify ActualExpected v1 v2 of
31+ case guardedUnify v1 v2 of
34 Unify k ->
32 Unify k ->
35− k [] onSuccess $ \vars problem ->
33+ k [] onSuccess $ \vars () ->
36 do t1 <- Type.toSrcType v1
34 do t1 <- Type.toSrcType v1
37 t2 <- Type.toSrcType v2
35 t2 <- Type.toSrcType v2
38 UF.union v1 v2 errorDescriptor
36 UF.union v1 v2 errorDescriptor
39− return (Err vars problem t1 t2)
37+ return (Err vars t1 t2)
42onSuccess :: [Variable] -> () -> IO Answer
40onSuccess :: [Variable] -> () -> IO Answer
@@ -51,58 +49,6 @@ errorDescriptor =
58− = BadFields [(N.Name, Maybe Reason)]
59− | MessyFields [N.Name] [N.Name] [N.Name]
62− | RigidClash N.Name N.Name
63− | NotPartOfSuper Type.SuperType
64− | RigidVarTooGeneric N.Name SpecificThing
65− | RigidSuperTooGeneric Type.SuperType N.Name SpecificThing
69− = SpecificSuper Type.SuperType
70− | SpecificType N.Name
77−flipReason :: Reason -> Reason
81− BadFields (map (fmap (fmap flipReason)) fields)
83− MessyFields both left right ->
84− MessyFields both right left
95− NotPartOfSuper super ->
98− RigidVarTooGeneric name specific ->
99− RigidVarTooGeneric name specific
101− RigidSuperTooGeneric super name specific ->
102− RigidSuperTooGeneric super name specific
106-- CPS UNIFIER
52-- CPS UNIFIER
@@ -110,7 +56,7 @@ newtype Unify a =
110 Unify (forall r.
56 Unify (forall r.
111 [Variable]
57 [Variable]
112 -> ([Variable] -> a -> IO r)
58 -> ([Variable] -> a -> IO r)
113− -> ([Variable] -> Problem -> IO r)
59+ -> ([Variable] -> () -> IO r)
@@ -167,100 +113,44 @@ register mkVar =
167 ok (var:vars) var
113 ok (var:vars) var
118+ Unify $ \vars _ err ->
122+try2 :: Unify () -> Unify () -> Unify ()
123+try2 (Unify k1) (Unify k2) =
124+ Unify $ \vars ok err ->
126+ ok1 vars1 () = k2 vars1 ok err
127+ err1 vars1 () = k2 vars1 err err
133+try3 :: Unify () -> Unify () -> Unify () -> Unify ()
135+ try2 u1 (try2 u2 u3)
171-- UNIFICATION HELPERS
139-- UNIFICATION HELPERS
174data Context =
142data Context =
176− { _orientation :: Orientation
177− , _first :: Variable
144+ { _first :: Variable
178 , _firstDesc :: Descriptor
145 , _firstDesc :: Descriptor
179 , _second :: Variable
146 , _second :: Variable
180 , _secondDesc :: Descriptor
147 , _secondDesc :: Descriptor
189reorient :: Context -> Context
151reorient :: Context -> Context
190−reorient (Context orientation var1 desc1 var2 desc2) =
152+reorient (Context var1 desc1 var2 desc2) =
194− ExpectedActual -> ActualExpected
195− ActualExpected -> ExpectedActual
197− Context otherOrientation var2 desc2 var1 desc1
153+ Context var2 desc2 var1 desc1
205− = Reason Bool (Maybe Reason)
209−mismatch :: Context -> Maybe Reason -> Unify a
210−mismatch context@(Context orientation var1 _ var2 _) maybeReason =
211− Unify $ \vars _ err ->
212− do anyInfinite <- liftM2 (||) (Occurs.occurs var1) (Occurs.occurs var2)
214− then err vars Infinite
216− do args1 <- collectArgs [] var1
217− args2 <- collectArgs [] var2
220− or <$> traverse detectDecoder (args1 ++ args2)
222− if length args1 /= length args2
224− do newVars <- foldM (subUnifyAnyway context) vars (zip args1 args2)
225− err newVars $ Reason hasDecoder $ Just $
226− MissingArgs (abs (length args2 - length args1))
228− err vars $ Reason hasDecoder $
234− fmap flipReason maybeReason
237−subUnifyAnyway :: Context -> [Variable] -> (Variable, Variable) -> IO [Variable]
238−subUnifyAnyway context vars (arg1, arg2) =
239− case subUnify context arg1 arg2 of
241− k vars (\vs _ -> return vs) (\vs _ -> return vs)
244−collectArgs :: [Variable] -> Variable -> IO [Variable]
245−collectArgs revArgs variable =
246− do (Descriptor content _ _ _) <- UF.get variable
248− Structure (Fun1 arg returnType) ->
249− collectArgs (arg : revArgs) returnType
252− return $ variable : revArgs
255−detectDecoder :: Variable -> IO Bool
256−detectDecoder variable =
257− do (Descriptor content _ _ _) <- UF.get variable
259− Structure (App1 home name [_]) ->
260− return (home == ModuleName.jsonDecode && name == "Decoder")
@@ -268,14 +158,14 @@ detectDecoder variable =
270merge :: Context -> Content -> Unify ()
160merge :: Context -> Content -> Unify ()
271−merge (Context _ var1 (Descriptor _ rank1 _ _) var2 (Descriptor _ rank2 _ _)) content =
161+merge (Context var1 (Descriptor _ rank1 _ _) var2 (Descriptor _ rank2 _ _)) content =
272 Unify $ \vars ok _ ->
162 Unify $ \vars ok _ ->
273 ok vars =<<
163 ok vars =<<
274 UF.union var1 var2 (Descriptor content (min rank1 rank2) noMark Nothing)
164 UF.union var1 var2 (Descriptor content (min rank1 rank2) noMark Nothing)
277fresh :: Context -> Content -> Unify Variable
167fresh :: Context -> Content -> Unify Variable
278−fresh (Context _ _ (Descriptor _ rank1 _ _) _ (Descriptor _ rank2 _ _)) content =
168+fresh (Context _ (Descriptor _ rank1 _ _) _ (Descriptor _ rank2 _ _)) content =
279 register $ UF.fresh $
169 register $ UF.fresh $
280 Descriptor content (min rank1 rank2) noMark Nothing
170 Descriptor content (min rank1 rank2) noMark Nothing
@@ -284,8 +174,8 @@ fresh (Context _ _ (Descriptor _ rank1 _ _) _ (Descriptor _ rank2 _ _)) content
284-- ACTUALLY UNIFY THINGS
174-- ACTUALLY UNIFY THINGS
287−guardedUnify :: Orientation -> Variable -> Variable -> Unify ()
177+guardedUnify :: Variable -> Variable -> Unify ()
288−guardedUnify orientation left right =
178+guardedUnify left right =
289 Unify $ \vars ok err ->
179 Unify $ \vars ok err ->
290 do equivalent <- UF.equivalent left right
180 do equivalent <- UF.equivalent left right
291 if equivalent
181 if equivalent
@@ -293,31 +183,18 @@ guardedUnify orientation left right =
294 do leftDesc <- UF.get left
184 do leftDesc <- UF.get left
295 rightDesc <- UF.get right
185 rightDesc <- UF.get right
296− putStrLn (toString leftDesc ++ " vs " ++ toString rightDesc)
297− case actuallyUnify (Context orientation left leftDesc right rightDesc) of
186+ case actuallyUnify (Context left leftDesc right rightDesc) of
298 Unify k ->
187 Unify k ->
299 k vars ok err
188 k vars ok err
302−toString :: Descriptor -> String
303−toString (Descriptor content _ _ _) =
305− FlexVar _ -> "FlexVar"
306− FlexSuper _ _ -> "FlexSuper"
307− RigidVar _ -> "RigidVar"
308− RigidSuper _ _ -> "RigidSuper"
309− Alias _ _ _ _ -> "Alias"
310− Structure _ -> "Structure"
314−subUnify :: Context -> Variable -> Variable -> Unify ()
191+subUnify :: Variable -> Variable -> Unify ()
315−subUnify context var1 var2 =
192+subUnify var1 var2 =
316− guardedUnify (_orientation context) var1 var2
193+ guardedUnify var1 var2
319actuallyUnify :: Context -> Unify ()
196actuallyUnify :: Context -> Unify ()
320−actuallyUnify context@(Context _ _ (Descriptor firstContent _ _ _) _ (Descriptor secondContent _ _ _)) =
197+actuallyUnify context@(Context _ (Descriptor firstContent _ _ _) _ (Descriptor secondContent _ _ _)) =
321 case firstContent of
198 case firstContent of
322 FlexVar _ ->
199 FlexVar _ ->
323 unifyFlex context firstContent secondContent
200 unifyFlex context firstContent secondContent
@@ -325,11 +202,11 @@ actuallyUnify context@(Context _ _ (Descriptor firstContent _ _ _) _ (Descriptor
325 FlexSuper super _ ->
202 FlexSuper super _ ->
326 unifyFlexSuper context super firstContent secondContent
203 unifyFlexSuper context super firstContent secondContent
328− RigidVar name ->
205+ RigidVar _ ->
329− unifyRigid context Nothing name firstContent secondContent
206+ unifyRigid context Nothing firstContent secondContent
331− RigidSuper super name ->
208+ RigidSuper super _ ->
332− unifyRigid context (Just super) name firstContent secondContent
209+ unifyRigid context (Just super) firstContent secondContent
334 Alias home name args realVar ->
211 Alias home name args realVar ->
335 unifyAlias context home name args realVar secondContent
212 unifyAlias context home name args realVar secondContent
@@ -384,8 +261,8 @@ unifyFlex context content otherContent =
384-- UNIFY RIGID VARIABLES
261-- UNIFY RIGID VARIABLES
387−unifyRigid :: Context -> Maybe SuperType -> N.Name -> Content -> Content -> Unify ()
264+unifyRigid :: Context -> Maybe SuperType -> Content -> Content -> Unify ()
388−unifyRigid context maybeSuper name content otherContent =
265+unifyRigid context maybeSuper content otherContent =
389 case otherContent of
266 case otherContent of
390 FlexVar _ ->
267 FlexVar _ ->
391 merge context content
268 merge context content
@@ -396,57 +273,27 @@ unifyRigid context maybeSuper name content otherContent =
396 if combineRigidSupers super otherSuper then
273 if combineRigidSupers super otherSuper then
397 merge context content
274 merge context content
399− mismatch context $ Just $
276+ mismatch
400− RigidSuperTooGeneric super name $ SpecificSuper otherSuper
402 Nothing ->
278 Nothing ->
403− mismatch context $ Just $
279+ mismatch
404− RigidVarTooGeneric name $ SpecificSuper otherSuper
406− RigidVar otherName ->
281+ RigidVar _ ->
407− mismatch context $ Just $
282+ mismatch
408− RigidClash name otherName
410− RigidSuper _ otherName ->
284+ RigidSuper _ _ ->
411− mismatch context $ Just $
285+ mismatch
412− RigidClash name otherName
414− Alias _ otherName _ _ ->
287+ Alias _ _ _ _ ->
415− mismatch context $ Just $
288+ mismatch
416− maybe RigidVarTooGeneric RigidSuperTooGeneric maybeSuper name $
417− SpecificType otherName
419− Structure flatType ->
290+ Structure _ ->
420− mismatch context $ Just $
291+ mismatch
421− maybe RigidVarTooGeneric RigidSuperTooGeneric maybeSuper name $
422− flatTypeToSpecificThing flatType
424 Error _ ->
293 Error _ ->
425 return ()
294 return ()
428−flatTypeToSpecificThing :: FlatType -> SpecificThing
429−flatTypeToSpecificThing flatType =
451-- UNIFY SUPER VARIABLES
298-- UNIFY SUPER VARIABLES
@@ -457,16 +304,14 @@ unifyFlexSuper context super content otherContent =
457 Structure flatType ->
304 Structure flatType ->
458 unifyFlexSuperStructure context super flatType
305 unifyFlexSuperStructure context super flatType
460− RigidVar name ->
307+ RigidVar _ ->
461− mismatch context $ Just $
308+ mismatch
462− RigidVarTooGeneric name (SpecificSuper super)
464− RigidSuper otherSuper name ->
310+ RigidSuper otherSuper _ ->
465 if combineRigidSupers otherSuper super then
311 if combineRigidSupers otherSuper super then
466 merge context otherContent
312 merge context otherContent
468− mismatch context $ Just $
314+ mismatch
469− RigidSuperTooGeneric otherSuper name (SpecificSuper super)
471 FlexVar _ ->
316 FlexVar _ ->
472 merge context content
317 merge context content
@@ -477,7 +322,7 @@ unifyFlexSuper context super content otherContent =
477 case otherSuper of
322 case otherSuper of
478 Number -> merge context content
323 Number -> merge context content
479 Comparable -> merge context content
324 Comparable -> merge context content
480− _ -> mismatch context Nothing -- NumberAppendableClash
325+ _ -> mismatch
482 Comparable ->
327 Comparable ->
483 case otherSuper of
328 case otherSuper of
@@ -491,17 +336,17 @@ unifyFlexSuper context super content otherContent =
491 Appendable -> merge context otherContent
336 Appendable -> merge context otherContent
492 Comparable -> merge context (Type.unnamedFlexSuper CompAppend)
337 Comparable -> merge context (Type.unnamedFlexSuper CompAppend)
493 CompAppend -> merge context otherContent
338 CompAppend -> merge context otherContent
494− Number -> mismatch context Nothing -- NumberAppendableClash
339+ Number -> mismatch
496 CompAppend ->
341 CompAppend ->
497 case otherSuper of
342 case otherSuper of
498 Comparable -> merge context content
343 Comparable -> merge context content
499 Appendable -> merge context content
344 Appendable -> merge context content
500 CompAppend -> merge context content
345 CompAppend -> merge context content
501− Number -> mismatch context Nothing -- NumberAppendableClash
346+ Number -> mismatch
503 Alias _ _ _ realVar ->
348 Alias _ _ _ realVar ->
504− subUnify context (_first context) realVar
349+ subUnify (_first context) realVar
506 Error _ ->
351 Error _ ->
507 return ()
352 return ()
@@ -543,12 +388,12 @@ unifyFlexSuperStructure context super flatType =
543 if atomMatchesSuper super home name then
388 if atomMatchesSuper super home name then
544 merge context (Structure flatType)
389 merge context (Structure flatType)
546− mismatch context $ Just $ NotPartOfSuper super
391+ mismatch
548 App1 home name [variable] | home == ModuleName.list && name == N.list ->
393 App1 home name [variable] | home == ModuleName.list && name == N.list ->
549 case super of
394 case super of
550 Number ->
395 Number ->
551− mismatch context $ Just $ NotPartOfSuper super
396+ mismatch
553 Appendable ->
398 Appendable ->
554 merge context (Structure flatType)
399 merge context (Structure flatType)
@@ -556,58 +401,57 @@ unifyFlexSuperStructure context super flatType =
556 Comparable ->
401 Comparable ->
557 do comparableOccursCheck context
402 do comparableOccursCheck context
558 merge context (Structure flatType)
403 merge context (Structure flatType)
559− unifyComparableRecursive (_orientation context) variable
404+ unifyComparableRecursive variable
561 CompAppend ->
406 CompAppend ->
562 do comparableOccursCheck context
407 do comparableOccursCheck context
563 merge context (Structure flatType)
408 merge context (Structure flatType)
564− unifyComparableRecursive (_orientation context) variable
409+ unifyComparableRecursive variable
566 Tuple1 a b maybeC ->
411 Tuple1 a b maybeC ->
567 case super of
412 case super of
568 Number ->
413 Number ->
569− mismatch context $ Just $ NotPartOfSuper super
414+ mismatch
571 Appendable ->
416 Appendable ->
572− mismatch context $ Just $ NotPartOfSuper super
417+ mismatch
574 Comparable ->
419 Comparable ->
575 do comparableOccursCheck context
420 do comparableOccursCheck context
576 merge context (Structure flatType)
421 merge context (Structure flatType)
577− let orientation = _orientation context
578− unifyComparableRecursive orientation a
422+ unifyComparableRecursive a
579− unifyComparableRecursive orientation b
423+ unifyComparableRecursive b
580 case maybeC of
424 case maybeC of
581 Nothing ->
425 Nothing ->
582 return ()
426 return ()
584 Just c ->
428 Just c ->
585− unifyComparableRecursive orientation c
429+ unifyComparableRecursive c
587 CompAppend ->
431 CompAppend ->
588− mismatch context $ Just $ NotPartOfSuper super
432+ mismatch
591− mismatch context $ Just $ NotPartOfSuper super
435+ mismatch
594-- TODO: is there some way to avoid doing this?
438-- TODO: is there some way to avoid doing this?
595-- Do type classes require occurs checks?
439-- Do type classes require occurs checks?
596comparableOccursCheck :: Context -> Unify ()
440comparableOccursCheck :: Context -> Unify ()
597−comparableOccursCheck (Context _ _ _ var _) =
441+comparableOccursCheck (Context _ _ var _) =
598 Unify $ \vars ok err ->
442 Unify $ \vars ok err ->
599 do hasOccurred <- Occurs.occurs var
443 do hasOccurred <- Occurs.occurs var
600 if hasOccurred
444 if hasOccurred
601− then err vars Infinite
445+ then err vars ()
602 else ok vars ()
446 else ok vars ()
605−unifyComparableRecursive :: Orientation -> Variable -> Unify ()
449+unifyComparableRecursive :: Variable -> Unify ()
606−unifyComparableRecursive orientation var =
450+unifyComparableRecursive var =
607 do compVar <- register $
451 do compVar <- register $
608 do (Descriptor _ rank _ _) <- UF.get var
452 do (Descriptor _ rank _ _) <- UF.get var
609 UF.fresh $ Descriptor (Type.unnamedFlexSuper Comparable) rank noMark Nothing
453 UF.fresh $ Descriptor (Type.unnamedFlexSuper Comparable) rank noMark Nothing
610− guardedUnify orientation compVar var
454+ guardedUnify compVar var
@@ -618,30 +462,60 @@ unifyAlias :: Context -> ModuleName.Canonical -> N.Name -> [(N.Name, Variable)]
618unifyAlias context home name args realVar otherContent =
462unifyAlias context home name args realVar otherContent =
619 case otherContent of
463 case otherContent of
620 FlexVar _ ->
464 FlexVar _ ->
621− merge context (Alias home name args realVar)
465+ merge context (Alias home name args realVar)
623 FlexSuper _ _ ->
467 FlexSuper _ _ ->
624− subUnify context realVar (_second context)
468+ subUnify realVar (_second context)
626 RigidVar _ ->
470 RigidVar _ ->
627− subUnify context realVar (_second context)
471+ subUnify realVar (_second context)
629 RigidSuper _ _ ->
473 RigidSuper _ _ ->
630− subUnify context realVar (_second context)
474+ subUnify realVar (_second context)
632 Alias otherHome otherName otherArgs otherRealVar ->
476 Alias otherHome otherName otherArgs otherRealVar ->
633− if name == otherName && home == otherHome then
477+ if name == otherName && home == otherHome then
634− do zipWithM_ (subUnify context) (map snd args) (map snd otherArgs)
478+ Unify $ \vars ok err ->
635− merge context otherContent
481+ case merge context otherContent of
485+ unifyAliasArgs vars context args otherArgs ok1 err
638− subUnify context realVar otherRealVar
488+ subUnify realVar otherRealVar
640 Structure _ ->
490 Structure _ ->
641− subUnify context realVar (_second context)
491+ subUnify realVar (_second context)
643 Error _ ->
493 Error _ ->
644− return ()
494+ return ()
497+unifyAliasArgs :: [Variable] -> Context -> [(N.Name,Variable)] -> [(N.Name,Variable)] -> ([Variable] -> () -> IO r) -> ([Variable] -> () -> IO r) -> IO r
498+unifyAliasArgs vars context args1 args2 ok err =
503+ case subUnify arg1 arg2 of
506+ (\vs () -> unifyAliasArgs vs context others1 others2 ok err)
507+ (\vs () -> unifyAliasArgs vs context others1 others2 err err)
@@ -657,159 +531,161 @@ unifyStructure context flatType content otherContent =
657 FlexSuper super _ ->
531 FlexSuper super _ ->
658 unifyFlexSuperStructure (reorient context) super flatType
532 unifyFlexSuperStructure (reorient context) super flatType
660− RigidVar name ->
534+ RigidVar _ ->
661− mismatch context $ Just $ RigidVarTooGeneric name (flatTypeToSpecificThing flatType)
535+ mismatch
663− RigidSuper super name ->
537+ RigidSuper _ _ ->
664− mismatch context $ Just $ RigidSuperTooGeneric super name (flatTypeToSpecificThing flatType)
538+ mismatch
666 Alias _ _ _ realVar ->
540 Alias _ _ _ realVar ->
667− subUnify context (_first context) realVar
541+ subUnify (_first context) realVar
669 Structure otherFlatType ->
543 Structure otherFlatType ->
670 case (flatType, otherFlatType) of
544 case (flatType, otherFlatType) of
671 (App1 home name args, App1 otherHome otherName otherArgs) ->
545 (App1 home name args, App1 otherHome otherName otherArgs) ->
672 if home == otherHome && name == otherName then
546 if home == otherHome && name == otherName then
673− do zipWithM_ (subUnify context) args otherArgs
547+ Unify $ \vars ok err ->
674− merge context otherContent
550+ case merge context otherContent of
676− else if isIntFloat home name otherHome otherName then
552+ k vars1 ok err
677− mismatch context (Just IntFloat)
553+ in
554+ unifyArgs vars context args otherArgs ok1 err
680− mismatch context Nothing
557+ mismatch
682− (Fun1 arg result, Fun1 otherArg otherResult) ->
559+ (Fun1 arg1 res1, Fun1 arg2 res2) ->
683− do subUnify context arg otherArg
560+ do try2
684− subUnify context result otherResult
561+ (subUnify arg1 arg2)
562+ (subUnify res1 res2)
685 merge context otherContent
563 merge context otherContent
687 (EmptyRecord1, EmptyRecord1) ->
565 (EmptyRecord1, EmptyRecord1) ->
688 merge context otherContent
566 merge context otherContent
690 (Record1 fields ext, EmptyRecord1) | Map.null fields ->
568 (Record1 fields ext, EmptyRecord1) | Map.null fields ->
691− subUnify context ext (_second context)
569+ subUnify ext (_second context)
693 (EmptyRecord1, Record1 fields ext) | Map.null fields ->
571 (EmptyRecord1, Record1 fields ext) | Map.null fields ->
694− subUnify context (_first context) ext
572+ subUnify (_first context) ext
696− (Record1 fields extension, Record1 otherFields otherExtension) ->
574+ (Record1 fields1 ext1, Record1 fields2 ext2) ->
697 Unify $ \vars ok err ->
575 Unify $ \vars ok err ->
698− do firstStructure <- gatherFields context fields extension
576+ do structure1 <- gatherFields fields1 ext1
699− secondStructure <- gatherFields context otherFields otherExtension
577+ structure2 <- gatherFields fields2 ext2
700− case unifyRecord context firstStructure secondStructure of
578+ case unifyRecord context structure1 structure2 of
701 Unify k ->
579 Unify k ->
702 k vars ok err
580 k vars ok err
704 (Tuple1 a b Nothing, Tuple1 x y Nothing) ->
582 (Tuple1 a b Nothing, Tuple1 x y Nothing) ->
705− do subUnify context a x
584+ (subUnify a x)
706− subUnify context b y
585+ (subUnify b y)
586+ merge context otherContent
708 (Tuple1 a b (Just c), Tuple1 x y (Just z)) ->
588 (Tuple1 a b (Just c), Tuple1 x y (Just z)) ->
709− do subUnify context a x
590+ (subUnify a x)
710− subUnify context b y
591+ (subUnify b y)
711− subUnify context c z
592+ (subUnify c z)
593+ merge context otherContent
714− mismatch context Nothing
596+ mismatch
716 Error _ ->
598 Error _ ->
717 return ()
599 return ()
720−isIntFloat :: ModuleName.Canonical -> N.Name -> ModuleName.Canonical -> N.Name -> Bool
721−isIntFloat home name otherHome otherName =
722− otherHome == ModuleName.basics
723− && home == ModuleName.basics
725− (name == N.int && otherName == N.float)
727− (name == N.float && otherName == N.int)
732−-- UNIFY RECORDS
606+unifyArgs :: [Variable] -> Context -> [Variable] -> [Variable] -> ([Variable] -> () -> IO r) -> ([Variable] -> () -> IO r) -> IO r
607+unifyArgs vars context args1 args2 ok err =
612+ case subUnify arg1 arg2 of
615+ (\vs () -> unifyArgs vs context others1 others2 ok err)
616+ (\vs () -> unifyArgs vs context others1 others2 err err)
735−unifyRecord :: Context -> RecordStructure -> RecordStructure -> Unify ()
621+ [] ->
736−unifyRecord context firstStructure secondStructure =
622+ case args2 of
737− do let (RecordStructure expFields expVar expStruct) = firstStructure
738− let (RecordStructure actFields actVar actStruct) = secondStructure
740− let sharedFields = Map.intersectionWith (,) expFields actFields
742− -- call after unifying extension, make sure record shape matches before
743− -- looking into whether the particular field types match.
744− let unifySharedFields otherFields ext =
745− do unifySharedFieldsHelp context sharedFields
746− let allFields = Map.union (Map.map fst sharedFields) otherFields
747− merge context (Structure (Record1 allFields ext))
749− let uniqueExpFields = Map.difference expFields actFields
750− let uniqueActFields = Map.difference actFields expFields
752− case (expStruct, Map.null uniqueExpFields, actStruct, Map.null uniqueActFields) of
753− (_, True, _, True) ->
754− do subUnify context expVar actVar
755− unifySharedFields Map.empty expVar
757− (Empty, _, _, False) ->
758− mismatch context $ Just $
759− MessyFields (Map.keys sharedFields) (Map.keys uniqueExpFields) (Map.keys uniqueActFields)
761− (_, False, Empty, _) ->
762− mismatch context $ Just $
763− MessyFields (Map.keys sharedFields) (Map.keys uniqueExpFields) (Map.keys uniqueActFields)
765− (_, False, _, True) ->
766− do subRecord <- fresh context (Structure (Record1 uniqueExpFields expVar))
767− subUnify context subRecord actVar
768− unifySharedFields Map.empty subRecord
770− (_, True, _, False) ->
771− do subRecord <- fresh context (Structure (Record1 uniqueActFields actVar))
772− subUnify context expVar subRecord
773− unifySharedFields Map.empty subRecord
775− (Extension, False, Extension, False) ->
776− do let subFields = Map.union uniqueExpFields uniqueActFields
777− subExt <- fresh context Type.unnamedFlexVar
778− expRecord <- fresh context (Structure (Record1 uniqueActFields subExt))
779− actRecord <- fresh context (Structure (Record1 uniqueExpFields subExt))
780− subUnify context expVar expRecord
781− subUnify context actRecord actVar
782− unifySharedFields subFields subExt
786−unifySharedFieldsHelp :: Context -> Map.Map N.Name (Variable, Variable) -> Unify ()
787−unifySharedFieldsHelp context sharedFields =
788− do badFields <- Map.traverseMaybeWithKey (unifyField context) sharedFields
789− case Map.toList badFields of
791− return ()
624+ ok vars ()
793− badFieldPairs ->
630+
794− mismatch context (Just (BadFields badFieldPairs))
631+-- UNIFY RECORDS
797−unifyField :: Context -> N.Name -> (Variable, Variable) -> Unify (Maybe (Maybe Reason))
634+unifyRecord :: Context -> RecordStructure -> RecordStructure -> Unify ()
635+unifyRecord context (RecordStructure fields1 ext1) (RecordStructure fields2 ext2) =
637+ sharedFields = Map.intersectionWith (,) fields1 fields2
638+ uniqueFields1 = Map.difference fields1 fields2
639+ uniqueFields2 = Map.difference fields2 fields1
641+ if Map.null uniqueFields1 then
643+ if Map.null uniqueFields2 then
645+ (subUnify ext1 ext2)
646+ (unifySharedFields context sharedFields Map.empty ext1)
649+ do subRecord <- fresh context (Structure (Record1 uniqueFields1 ext1))
651+ (subUnify subRecord ext2)
652+ (unifySharedFields context sharedFields Map.empty subRecord)
656+ if Map.null uniqueFields2 then
657+ do subRecord <- fresh context (Structure (Record1 uniqueFields2 ext2))
659+ (subUnify ext1 subRecord)
660+ (unifySharedFields context sharedFields Map.empty subRecord)
663+ do let otherFields = Map.union uniqueFields1 uniqueFields2
664+ ext <- fresh context Type.unnamedFlexVar
665+ sub1 <- fresh context (Structure (Record1 uniqueFields1 ext))
666+ sub2 <- fresh context (Structure (Record1 uniqueFields2 ext))
668+ (subUnify ext1 sub2)
669+ (subUnify sub1 ext2)
670+ (unifySharedFields context sharedFields otherFields ext)
673+unifySharedFields :: Context -> Map.Map N.Name (Variable, Variable) -> Map.Map N.Name Variable -> Variable -> Unify ()
674+unifySharedFields context sharedFields otherFields ext =
675+ do matchingFields <- Map.traverseMaybeWithKey unifyField sharedFields
676+ if Map.size sharedFields == Map.size matchingFields
677+ then merge context (Structure (Record1 (Map.union matchingFields otherFields) ext))
681+unifyField :: N.Name -> (Variable, Variable) -> Unify (Maybe Variable)
798−unifyField context _ (actual, expected) =
682+unifyField _ (actual, expected) =
799 Unify $ \vars ok _ ->
683 Unify $ \vars ok _ ->
800− case subUnify context actual expected of
684+ case subUnify actual expected of
801 Unify k ->
685 Unify k ->
687+ (\vs () -> ok vs (Just actual))
803 (\vs () -> ok vs Nothing)
688 (\vs () -> ok vs Nothing)
@@ -819,30 +695,21 @@ unifyField context _ (actual, expected) =
819data RecordStructure =
695data RecordStructure =
820 RecordStructure
696 RecordStructure
821 { _fields :: Map.Map N.Name Variable
697 { _fields :: Map.Map N.Name Variable
822− , _extVar :: Variable
698+ , _extension :: Variable
823− , _extStruct :: ExtensionStructure
827−data ExtensionStructure
832−gatherFields :: Context -> Map.Map N.Name Variable -> Variable -> IO RecordStructure
702+gatherFields :: Map.Map N.Name Variable -> Variable -> IO RecordStructure
833−gatherFields context fields variable =
703+gatherFields fields variable =
834 do (Descriptor content _ _ _) <- UF.get variable
704 do (Descriptor content _ _ _) <- UF.get variable
835 case content of
705 case content of
836 Structure (Record1 subFields subExt) ->
706 Structure (Record1 subFields subExt) ->
837− gatherFields context (Map.union fields subFields) subExt
707+ gatherFields (Map.union fields subFields) subExt
839− Structure EmptyRecord1 ->
840− return (RecordStructure fields variable Empty)
842 Alias _ _ _ var ->
709 Alias _ _ _ var ->
843 -- TODO may be dropping useful alias info here
710 -- TODO may be dropping useful alias info here
844− gatherFields context fields var
711+ gatherFields fields var
847− return (RecordStructure fields variable Extension)
714+ return (RecordStructure fields variable)