@@ -125,42 +125,6 @@ reasonToProblem orientation maybeReason =
125125 Special (Error.flipReason reason)
126126
127127
128−badRigid :: Maybe Text -> Error.Reason
129−badRigid maybeName =
130− Error.BadVar (Just (Error.Rigid maybeName)) Nothing
131−
132−
133−badSuper :: Super -> Error.Reason
134−badSuper super =
135− Error.BadVar (Just (errorSuper super)) Nothing
136−
137−
138−badSupers :: Super -> Super -> Error.Reason
139−badSupers super1 super2 =
140− Error.BadVar (Just (errorSuper super1)) (Just (errorSuper super2))
141−
142−
143−doubleBad :: Error.VarType -> Error.VarType -> Error.Reason
144−doubleBad vt1 vt2 =
145− Error.BadVar (Just vt1) (Just vt2)
146−
147−
148−errorSuper :: Super -> Error.VarType
149−errorSuper super =
150− case super of
151− Number ->
152− Error.Number
153−
154− Comparable ->
155− Error.Comparable
156−
157− Appendable ->
158− Error.Appendable
159−
160− CompAppend ->
161− Error.CompAppend
162−
163−
164128
165129-- MERGE
166130
@@ -210,25 +174,28 @@ subUnify context var1 var2 =
210174actuallyUnify :: Context -> Unify ()
211175actuallyUnify context@(Context _ _ (Descriptor firstContent _ _ _) _ (Descriptor secondContent _ _ _)) =
212176 case firstContent of
213− Error _ ->
214− -- If there was an error, just pretend it is okay. This lets us avoid
215− -- "cascading" errors where one problem manifests as multiple message.
216− return ()
217−
218− Var Flex Nothing _ ->
177+ FlexVar _ ->
219178 unifyFlex context secondContent
220179
221− Var Flex (Just super) _ ->
180+ FlexSuper super _ ->
222181 unifyFlexSuper context super firstContent secondContent
223182
224− Var Rigid maybeSuper maybeName ->
225− unifyRigid context maybeSuper maybeName firstContent secondContent
183+ RigidVar name ->
184+ unifyRigid context Nothing name firstContent secondContent
185+
186+ RigidSuper super name ->
187+ unifyRigid context (Just super) name firstContent secondContent
226188
227189 Alias name args realVar ->
228190 unifyAlias context name args realVar secondContent
229191
230− Structure term ->
231− unifyStructure context term firstContent secondContent
192+ Structure flatType ->
193+ unifyStructure context flatType firstContent secondContent
194+
195+ Error _ ->
196+ -- If there was an error, just pretend it is okay. This lets us avoid
197+ -- "cascading" errors where one problem manifests as multiple message.
198+ return ()
232199
233200
234201
@@ -241,10 +208,18 @@ unifyFlex context otherContent =
241208 Error _ ->
242209 return ()
243210
244− Var Flex _ _ ->
211+ -- TODO see if wildcarding makes a noticable perf difference
212+
213+ FlexVar _ ->
214+ merge context otherContent
215+
216+ FlexSuper _ _ ->
217+ merge context otherContent
218+
219+ RigidVar _ ->
245220 merge context otherContent
246221
247− Var Rigid _ _ ->
222+ RigidSuper _ _ ->
248223 merge context otherContent
249224
250225 Alias _ _ _ ->
@@ -258,35 +233,61 @@ unifyFlex context otherContent =
258233-- UNIFY RIGID VARIABLES
259234
260235
261−unifyRigid :: Context -> Maybe Super -> Maybe Text -> Content -> Content -> Unify ()
262−unifyRigid context maybeSuper maybeName content otherContent =
236+unifyRigid :: Context -> Maybe Super -> Text -> Content -> Content -> Unify ()
237+unifyRigid context maybeSuper name content otherContent =
263238 case otherContent of
264− Error _ ->
265− return ()
239+ FlexVar _ ->
240+ merge context content
266241
267− Var Flex otherMaybeSuper _ ->
268− case (maybeSuper, otherMaybeSuper) of
269− (_, Nothing) ->
242+ FlexSuper otherSuper _ ->
243+ case maybeSuper of
244+ Just super ->
245+ if combineRigidSupers super otherSuper then
270246 merge context content
247+ else
248+ mismatch context $ Just $
249+ Error.RigidSuperTooGeneric super name $ Error.SpecificSuper otherSuper
271250
272− (Nothing, Just _) ->
273− mismatch context (Just (badRigid maybeName))
251+ Nothing ->
252+ mismatch context $ Just $
253+ Error.RigidVarTooGeneric name $ Error.SpecificSuper otherSuper
274254
275− (Just super, Just otherSuper) ->
276− if combineRigidSupers super otherSuper then
277− merge context content
278− else
279− mismatch context (Just (badRigid maybeName))
255+ RigidVar otherName ->
256+ mismatch context $ Just $
257+ Error.RigidClash name otherName
280258
281− Var Rigid _ otherMaybeName ->
259+ RigidSuper _ otherName ->
282260 mismatch context $ Just $
283− doubleBad (Error.Rigid maybeName) (Error.Rigid otherMaybeName)
261+ Error.RigidClash name otherName
284262
285− Alias _ _ _ ->
286− mismatch context (Just (badRigid maybeName))
263+ Alias otherName _ _ ->
264+ mismatch context $ Just $
265+ maybe Error.RigidVarTooGeneric Error.RigidSuperTooGeneric maybeSuper name $
266+ Error.SpecificType otherName
287267
288− Structure _ ->
289− mismatch context (Just (badRigid maybeName))
268+ Structure flatType ->
269+ mismatch context $ Just $
270+ maybe Error.RigidVarTooGeneric Error.RigidSuperTooGeneric maybeSuper name $
271+ flatTypeToSpecificThing flatType
272+
273+ Error _ ->
274+ return ()
275+
276+
277+flatTypeToSpecificThing :: FlatType -> Error.SpecificThing
278+flatTypeToSpecificThing flatType =
279+ case flatType of
280+ App1 name _ ->
281+ Error.SpecificType name
282+
283+ Fun1 _ _ ->
284+ Error.SpecificFunction
285+
286+ EmptyRecord1 ->
287+ Error.SpecificRecord
288+
289+ Record1 _ _ ->
290+ Error.SpecificRecord
290291
291292
292293
@@ -296,49 +297,51 @@ unifyRigid context maybeSuper maybeName content otherContent =
296297unifyFlexSuper :: Context -> Super -> Content -> Content -> Unify ()
297298unifyFlexSuper context super content otherContent =
298299 case otherContent of
299− Structure term ->
300− unifyFlexSuperStructure context super term
300+ Structure flatType ->
301+ unifyFlexSuperStructure context super flatType
301302
302− Var Rigid Nothing maybeName ->
303− mismatch context (Just (doubleBad (errorSuper super) (Error.Rigid maybeName)))
303+ RigidVar name ->
304+ mismatch context $ Just $
305+ Error.RigidVarTooGeneric name (Error.SpecificSuper super)
304306
305− Var Rigid (Just otherSuper) maybeName ->
307+ RigidSuper otherSuper name ->
306308 if combineRigidSupers otherSuper super then
307309 merge context otherContent
308310 else
309− mismatch context $ Just $ badRigid maybeName
311+ mismatch context $ Just $
312+ Error.RigidSuperTooGeneric otherSuper name (Error.SpecificSuper super)
310313
311− Var Flex Nothing _ ->
314+ FlexVar _ ->
312315 merge context content
313316
314− Var Flex (Just otherSuper) _ ->
317+ FlexSuper otherSuper _ ->
315318 case super of
316319 Number ->
317320 case otherSuper of
318321 Number -> merge context content
319322 Comparable -> merge context content
320− _ -> mismatch context $ Just $ badSupers super otherSuper
323+ _ -> mismatch context Nothing -- Error.NumberAppendableClash
321324
322325 Comparable ->
323326 case otherSuper of
324327 Comparable -> merge context otherContent
325328 Number -> merge context otherContent
326− Appendable -> merge context (Var Flex (Just CompAppend) Nothing)
329+ Appendable -> merge context (Type.unnamedFlexSuper CompAppend)
327330 CompAppend -> merge context otherContent
328331
329332 Appendable ->
330333 case otherSuper of
331334 Appendable -> merge context otherContent
332− Comparable -> merge context (Var Flex (Just CompAppend) Nothing)
335+ Comparable -> merge context (Type.unnamedFlexSuper CompAppend)
333336 CompAppend -> merge context otherContent
334− Number -> mismatch context $ Just $ badSupers super otherSuper
337+ Number -> mismatch context Nothing -- Error.NumberAppendableClash
335338
336339 CompAppend ->
337340 case otherSuper of
338341 Comparable -> merge context content
339342 Appendable -> merge context content
340343 CompAppend -> merge context content
341− Number -> mismatch context $ Just $ badSupers super otherSuper
344+ Number -> mismatch context Nothing -- Error.NumberAppendableClash
342345
343346 Alias _ _ realVar ->
344347 subUnify context (_first context) realVar
@@ -371,54 +374,54 @@ atomMatchesSuper super name =
371374
372375
373376unifyFlexSuperStructure :: Context -> Super -> FlatType -> Unify ()
374−unifyFlexSuperStructure context super term =
375− do case term of
376− App1 name [] ->
377− if atomMatchesSuper super name then
378− merge context (Structure term)
379− else
380− mismatch context (Just (badSuper super))
381−
382− App1 name [variable] | name == Var.list ->
383− case super of
384− Number ->
385− mismatch context (Just (badSuper super))
386−
387− Appendable ->
388− merge context (Structure term)
389−
390− Comparable ->
391− do comparableOccursCheck context
392− merge context (Structure term)
393− unifyComparableRecursive (_orientation context) variable
377+unifyFlexSuperStructure context super flatType =
378+ case flatType of
379+ App1 name [] ->
380+ if atomMatchesSuper super name then
381+ merge context (Structure flatType)
382+ else
383+ mismatch context $ Just $ Error.NotPartOfSuper super
384+
385+ App1 name [variable] | name == Var.list ->
386+ case super of
387+ Number ->
388+ mismatch context $ Just $ Error.NotPartOfSuper super
394389
395− CompAppend ->
396− do comparableOccursCheck context
397− merge context (Structure term)
398− unifyComparableRecursive (_orientation context) variable
390+ Appendable ->
391+ merge context (Structure flatType)
399392
400− App1 name args | Var.isTuple name ->
401− case super of
402− Number ->
403− mismatch context (Just (badSuper super))
393+ Comparable ->
394+ do comparableOccursCheck context
395+ merge context (Structure flatType)
396+ unifyComparableRecursive (_orientation context) variable
404397
405− Appendable ->
406− mismatch context (Just (badSuper super))
398+ CompAppend ->
399+ do comparableOccursCheck context
400+ merge context (Structure flatType)
401+ unifyComparableRecursive (_orientation context) variable
407402
408− Comparable ->
409− if length args > 6 then
410− mismatch context (Just (Error.TooLongComparableTuple (length args)))
403+ App1 name args | Var.isTuple name ->
404+ case super of
405+ Number ->
406+ mismatch context $ Just $ Error.NotPartOfSuper super
411407
412− else
413− do comparableOccursCheck context
414− merge context (Structure term)
415− mapM_ (unifyComparableRecursive (_orientation context)) args
408+ Appendable ->
409+ mismatch context $ Just $ Error.NotPartOfSuper super
416410
417− CompAppend ->
418− mismatch context (Just (badSuper super))
411+ Comparable ->
412+ if length args > 6 then
413+ mismatch context (Just (Error.TooLongComparableTuple (length args)))
419414
420− _ ->
421− mismatch context (Just (badSuper super))
415+ else
416+ do comparableOccursCheck context
417+ merge context (Structure flatType)
418+ mapM_ (unifyComparableRecursive (_orientation context)) args
419+
420+ CompAppend ->
421+ mismatch context $ Just $ Error.NotPartOfSuper super
422+
423+ _ ->
424+ mismatch context $ Just $ Error.NotPartOfSuper super
422425
423426
424427-- TODO: is there some way to avoid doing this?
@@ -435,7 +438,7 @@ unifyComparableRecursive :: Orientation -> Variable -> Unify ()
435438unifyComparableRecursive orientation var =
436439 do compVar <- liftIO $
437440 do (Descriptor _ rank _ _) <- UF.descriptor var
438− UF.fresh $ Descriptor (Var Flex (Just Comparable) Nothing) rank noMark Nothing
441+ UF.fresh $ Descriptor (Type.unnamedFlexSuper Comparable) rank noMark Nothing
439442
440443 lift $ TS.register compVar
441444
@@ -465,13 +468,16 @@ collectArgsHelp revArgs variable =
465468unifyAlias :: Context -> Var.Canonical -> [(Text, Variable)] -> Variable -> Content -> Unify ()
466469unifyAlias context name args realVar otherContent =
467470 case otherContent of
468− Error _ ->
469− return ()
470−
471− Var Flex Nothing _ ->
471+ FlexVar _ ->
472472 merge context (Alias name args realVar)
473473
474− Var _ _ _ ->
474+ FlexSuper _ _ ->
475+ subUnify context realVar (_second context)
476+
477+ RigidVar _ ->
478+ subUnify context realVar (_second context)
479+
480+ RigidSuper _ _ ->
475481 subUnify context realVar (_second context)
476482
477483 Alias otherName otherArgs otherRealVar ->
@@ -485,31 +491,34 @@ unifyAlias context name args realVar otherContent =
485491 Structure _ ->
486492 subUnify context realVar (_second context)
487493
494+ Error _ ->
495+ return ()
496+
488497
489498
490499-- UNIFY STRUCTURES
491500
492501
493502unifyStructure :: Context -> FlatType -> Content -> Content -> Unify ()
494−unifyStructure context term content otherContent =
503+unifyStructure context flatType content otherContent =
495504 case otherContent of
496− Error _ ->
497− return ()
498−
499− Var Flex Nothing _ ->
505+ FlexVar _ ->
500506 merge context content
501507
502− Var Flex (Just super) _ ->
503− unifyFlexSuperStructure (reorient context) super term
508+ FlexSuper super _ ->
509+ unifyFlexSuperStructure (reorient context) super flatType
504510
505− Var Rigid _ maybeName ->
506− mismatch context (Just (Error.flipReason (badRigid maybeName)))
511+ RigidVar name ->
512+ mismatch context $ Just $ Error.RigidVarTooGeneric name (flatTypeToSpecificThing flatType)
513+
514+ RigidSuper super name ->
515+ mismatch context $ Just $ Error.RigidSuperTooGeneric super name (flatTypeToSpecificThing flatType)
507516
508517 Alias _ _ realVar ->
509518 subUnify context (_first context) realVar
510519
511520 Structure otherTerm ->
512− case (term, otherTerm) of
521+ case (flatType, otherTerm) of
513522 (App1 name args, App1 otherName otherArgs) ->
514523 if name == otherName then
515524 do zipWithM_ (subUnify context) args otherArgs
@@ -543,6 +552,10 @@ unifyStructure context term content otherContent =
543552 _ ->
544553 mismatch context Nothing
545554
555+ Error _ ->
556+ return ()
557+
558+
546559
547560isIntFloat :: Var.Canonical -> Var.Canonical -> Bool
548561isIntFloat name otherName =
@@ -595,7 +608,7 @@ unifyRecord context firstStructure secondStructure =
595608
596609 (Extension, False, Extension, False) ->
597610 do let subFields = Map.union uniqueExpFields uniqueActFields
598− subExt <- fresh context (Var Flex Nothing Nothing)
611+ subExt <- fresh context Type.unnamedFlexVar
599612 expRecord <- fresh context (Structure (Record1 uniqueActFields subExt))
600613 actRecord <- fresh context (Structure (Record1 uniqueExpFields subExt))
601614 subUnify context expVar expRecord