@@ -11,6 +11,7 @@ import Data.Text (Text)
11import qualified AST.Variable as Var
11import qualified AST.Variable as Var
12import qualified Reporting.Region as R
12import qualified Reporting.Region as R
13import qualified Reporting.Error.Type as Error
13import qualified Reporting.Error.Type as Error
14+import qualified Type.Occurs as Occurs
14import qualified Type.State as TS
15import qualified Type.State as TS
15import Type.Type as Type
16import Type.Type as Type
16import qualified Type.UnionFind as UF
17import qualified Type.UnionFind as UF
@@ -48,7 +49,8 @@ type Unify =
48 ExceptT Mismatch TS.Solver
49 ExceptT Mismatch TS.Solver
51−data Context = Context
52+data Context =
52 { _orientation :: Orientation
54 { _orientation :: Orientation
53 , _first :: Variable
55 , _first :: Variable
54 , _firstDesc :: Descriptor
56 , _firstDesc :: Descriptor
@@ -152,8 +154,8 @@ merge (Context _ var1 (Descriptor _ rank1 _ _) var2 (Descriptor _ rank2 _ _)) co
154mergeHelp :: Variable -> Variable -> Content -> Int -> IO ()
156mergeHelp :: Variable -> Variable -> Content -> Int -> IO ()
155−mergeHelp var1 second newContent newRank =
157+mergeHelp var1 var2 newContent newRank =
156− UF.union var1 second $
158+ UF.union var1 var2 $
157 Descriptor
159 Descriptor
158 { _content = newContent
160 { _content = newContent
159 , _rank = newRank
161 , _rank = newRank
@@ -384,7 +386,7 @@ atomMatchesSuper super name =
385unifyFlexSuperStructure :: Context -> Super -> FlatType -> Unify ()
387unifyFlexSuperStructure :: Context -> Super -> FlatType -> Unify ()
386unifyFlexSuperStructure context super term =
388unifyFlexSuperStructure context super term =
387− do appStructure <- liftIO (collectApps (Structure term))
389+ do appStructure <- liftIO (collectApps term)
388 case appStructure of
390 case appStructure of
390 mismatch context (Just (badSuper super))
392 mismatch context (Just (badSuper super))
@@ -398,11 +400,13 @@ unifyFlexSuperStructure context super term =
398 merge context (Structure term)
400 merge context (Structure term)
400 Comparable ->
402 Comparable ->
403+ do comparableOccursCheck context
401− do merge context (Structure term)
404+ merge context (Structure term)
402 unifyComparableRecursive (_orientation context) variable
405 unifyComparableRecursive (_orientation context) variable
404 CompAppend ->
407 CompAppend ->
408+ do comparableOccursCheck context
405− do merge context (Structure term)
409+ merge context (Structure term)
406 unifyComparableRecursive (_orientation context) variable
410 unifyComparableRecursive (_orientation context) variable
408 Tuple entries ->
412 Tuple entries ->
@@ -418,13 +422,24 @@ unifyFlexSuperStructure context super term =
418 mismatch context (Just (Error.TooLongComparableTuple (length entries)))
422 mismatch context (Just (Error.TooLongComparableTuple (length entries)))
425+ do comparableOccursCheck context
421− do merge context (Structure term)
426+ merge context (Structure term)
422 mapM_ (unifyComparableRecursive (_orientation context)) entries
427 mapM_ (unifyComparableRecursive (_orientation context)) entries
424 CompAppend ->
429 CompAppend ->
425 mismatch context (Just (badSuper super))
430 mismatch context (Just (badSuper super))
433+-- TODO: is there some way to avoid doing this?
434+-- Do type classes require occurs checks?
435+comparableOccursCheck :: Context -> Unify ()
436+comparableOccursCheck (Context _ _ _ var _) =
437+ do hasOccurred <- liftIO $ Occurs.occurs var
439+ then throwError (Mismatch Nothing)
428unifyComparableRecursive :: Orientation -> Variable -> Unify ()
443unifyComparableRecursive :: Orientation -> Variable -> Unify ()
429unifyComparableRecursive orientation var =
444unifyComparableRecursive orientation var =
430 do compVar <-
445 do compVar <-
@@ -447,22 +462,27 @@ data AppStructure
450−collectApps :: Content -> IO AppStructure
465+collectApps :: FlatType -> IO AppStructure
451−collectApps content =
466+collectApps term =
452− collectAppsHelp [] content
469+ collectAppsHelp [arg] =<< getContent func
455collectAppsHelp :: [Variable] -> Content -> IO AppStructure
475collectAppsHelp :: [Variable] -> Content -> IO AppStructure
456collectAppsHelp args content =
476collectAppsHelp args content =
457 case (content, args) of
477 case (content, args) of
458 (Structure (App1 func arg), _) ->
478 (Structure (App1 func arg), _) ->
459− collectAppsHelp (args ++ [arg]) =<< getContent func
479+ collectAppsHelp (arg : args) =<< getContent func
461 (Atom name, [arg]) | Var.isList name ->
481 (Atom name, [arg]) | Var.isList name ->
462 return (List arg)
482 return (List arg)
464 (Atom name, _) | Var.isTuple name ->
484 (Atom name, _) | Var.isTuple name ->
465− return (Tuple args)
485+ return (Tuple (reverse args))
468 return Other
488 return Other