@@ -1,12 +1,12 @@
1{-# OPTIONS_GHC -Wall #-}
1{-# OPTIONS_GHC -Wall #-}
2module Type.Type where
2module Type.Type where
4+import Control.Monad (when)
4import Control.Monad.State (StateT, liftIO)
5import Control.Monad.State (StateT, liftIO)
5import qualified Control.Monad.State as State
6import qualified Control.Monad.State as State
7+import qualified Data.Char as Char
6import qualified Data.List as List
8import qualified Data.List as List
7import qualified Data.Map as Map
9import qualified Data.Map as Map
8−import qualified Data.Set as Set
9−import qualified Data.Traversable as Traverse (traverse)
10import qualified Data.UnionFind.IO as UF
10import qualified Data.UnionFind.IO as UF
12import qualified AST.Type as T
12import qualified AST.Type as T
@@ -185,13 +185,7 @@ mkVar maybeSuper =
186mkNamedVar :: Flex -> String -> IO Variable
186mkNamedVar :: Flex -> String -> IO Variable
187mkNamedVar flex name =
187mkNamedVar flex name =
188− UF.fresh $ mkDescriptor $ Var flex (toSuper name) $
188+ UF.fresh $ mkDescriptor $ Var flex (toSuper name) (Just name)
197toSuper :: String -> Maybe Super
191toSuper :: String -> Maybe Super
@@ -259,8 +253,8 @@ existsNumber f =
259-- never have to do extra work, particularly nice for aliased types
253-- never have to do extra work, particularly nice for aliased types
260toSrcType :: Variable -> IO T.Canonical
254toSrcType :: Variable -> IO T.Canonical
261toSrcType variable =
255toSrcType variable =
262− do usedNames <- getVarNames variable
256+ do takenNames <- State.execStateT (getVarNames variable) Map.empty
263− State.evalStateT (variableToSrcType variable) (makeNameState usedNames)
257+ State.evalStateT (variableToSrcType variable) (makeNameState takenNames)
266variableToSrcType :: Variable -> StateT NameState IO T.Canonical
260variableToSrcType :: Variable -> StateT NameState IO T.Canonical
@@ -297,7 +291,7 @@ contentToSrcType variable content =
297 return (T.Var freshName)
291 return (T.Var freshName)
299 Alias name args realVariable ->
293 Alias name args realVariable ->
300− do srcArgs <- mapM (\(arg,tvar) -> (,) arg <$> variableToSrcType tvar) args
294+ do srcArgs <- traverse (traverse variableToSrcType) args
301 srcType <- variableToSrcType realVariable
295 srcType <- variableToSrcType realVariable
302 return (T.Aliased name srcArgs (T.Filled srcType))
296 return (T.Aliased name srcArgs (T.Filled srcType))
@@ -327,7 +321,7 @@ termToSrcType term =
327 return $ T.Record [] Nothing
321 return $ T.Record [] Nothing
329 Record1 fields extension ->
323 Record1 fields extension ->
330− do srcFields <- Map.toList <$> Traverse.traverse variableToSrcType fields
324+ do srcFields <- Map.toList <$> traverse variableToSrcType fields
331 srcExt <- T.iteratedDealias <$> variableToSrcType extension
325 srcExt <- T.iteratedDealias <$> variableToSrcType extension
333 case srcExt of
327 case srcExt of
@@ -346,112 +340,163 @@ termToSrcType term =
348data NameState = NameState
342data NameState = NameState
349− { _freeNames :: [String]
343+ { _taken :: TakenNames
350− , _numberPrimes :: Int
344+ , _normals :: Int
351− , _comparablePrimes :: Int
345+ , _numbers :: Int
352− , _appendablePrimes :: Int
346+ , _comparables :: Int
353− , _compAppendPrimes :: Int
347+ , _appendables :: Int
348+ , _compAppends :: Int
357−makeNameState :: Set.Set String -> NameState
352+type TakenNames = Map.Map String Variable
358−makeNameState usedNames =
361− map (:suffix) ['a'..'z']
364− concatMap makeName ("" : map show [ (1 :: Int) .. ])
366− freeNames =
355+makeNameState :: TakenNames -> NameState
367− filter (\name -> Set.notMember name usedNames) allNames
356+makeNameState taken =
369− NameState freeNames 0 0 0 0
357+ NameState taken 0 0 0 0 0
372getFreshName :: (Monad m) => Maybe Super -> StateT NameState m String
360getFreshName :: (Monad m) => Maybe Super -> StateT NameState m String
373getFreshName maybeSuper =
361getFreshName maybeSuper =
374 case maybeSuper of
362 case maybeSuper of
375 Nothing ->
363 Nothing ->
376− do names <- State.gets _freeNames
364+ do index <- State.gets _normals
365+ taken <- State.gets _taken
366+ let (uniqueName, newIndex) = getFreshNormal index taken
377− State.modify (\state -> state { _freeNames = tail names })
367+ State.modify (\state -> state { _normals = newIndex })
378− return (head names)
368+ return uniqueName
380 Just Number ->
370 Just Number ->
381− do primes <- State.gets _numberPrimes
371+ getFreshSuper "number" _numbers (\index state -> state { _numbers = index })
382− State.modify (\state -> state { _numberPrimes = primes + 1 })
383− return ("number" ++ replicate primes '\'')
385 Just Comparable ->
373 Just Comparable ->
386− do primes <- State.gets _comparablePrimes
374+ getFreshSuper "comparable" _comparables (\index state -> state { _comparables = index })
387− State.modify (\state -> state { _comparablePrimes = primes + 1 })
388− return ("comparable" ++ replicate primes '\'')
390 Just Appendable ->
376 Just Appendable ->
391− do primes <- State.gets _appendablePrimes
377+ getFreshSuper "appendable" _appendables (\index state -> state { _appendables = index })
392− State.modify (\state -> state { _appendablePrimes = primes + 1 })
393− return ("appendable" ++ replicate primes '\'')
395 Just CompAppend ->
379 Just CompAppend ->
396− do primes <- State.gets _compAppendPrimes
380+ getFreshSuper "compappend" _compAppends (\index state -> state { _compAppends = index })
397− State.modify (\state -> state { _compAppendPrimes = primes + 1 })
381+
398− return ("compappend" ++ replicate primes '\'')
382+
383+getFreshNormal :: Int -> TakenNames -> (String, Int)
384+getFreshNormal index taken =
390+ Char.chr (97 + letter) : if postfix <= 0 then "" else show postfix
392+ if Map.member name taken then
393+ getFreshNormal (index + 1) taken
402+ -> (NameState -> Int)
403+ -> (Int -> NameState -> NameState)
404+ -> StateT NameState m String
405+getFreshSuper name getter setter =
406+ do index <- State.gets getter
407+ taken <- State.gets _taken
408+ let (uniqueName, newIndex) = getFreshSuperHelp name index taken
409+ State.modify (setter newIndex)
413+getFreshSuperHelp :: String -> Int -> TakenNames -> (String, Int)
414+getFreshSuperHelp name index taken =
417+ if index <= 0 then name else name ++ show index
419+ if Map.member newName taken then
420+ getFreshSuperHelp name (index + 1) taken
423+ (newName, index + 1)
402-- GET ALL VARIABLE NAMES
427-- GET ALL VARIABLE NAMES
405−getVarNames :: Variable -> IO (Set.Set String)
430+getVarNames :: Variable -> StateT TakenNames IO ()
406getVarNames var =
431getVarNames var =
407− do desc <- UF.descriptor var
432+ do desc <- liftIO $ UF.descriptor var
408− if _mark desc == getVarNamesMark
433+ case _mark desc == getVarNamesMark of
410− return Set.empty
435+ return ()
413− do UF.setDescriptor var (desc { _mark = getVarNamesMark })
438+ do liftIO $ UF.setDescriptor var (desc { _mark = getVarNamesMark })
414− getVarNamesHelp (_content desc)
439+ case _content desc of
417−getVarNamesHelp :: Content -> IO (Set.Set String)
418−getVarNamesHelp content =
420− Var _ _ (Just name) ->
446+ Var _ _ Nothing ->
421− return (Set.singleton name)
447+ return ()
423− Var _ _ Nothing ->
449+ Var flex maybeSuper (Just name) ->
424− return Set.empty
450+ do oldTaken <- State.get
451+ newTaken <- liftIO $ addVarName 0 name var flex maybeSuper oldTaken
426− Structure term ->
454+ Alias _ args realVar ->
427− getVarNamesTerm term
455+ do mapM_ (getVarNames . snd) args
429− Alias _name args realVar ->
458+ Structure (App1 func arg) ->
430− do let argSet = Set.fromList (map fst args)
431− realSet <- getVarNames realVar
459+ do getVarNames func
432− sets <- mapM (getVarNames . snd) args
460+ getVarNames arg
433− return (Set.unions (realSet : argSet : sets))
435− Atom _ ->
462+ Structure (Fun1 arg body) ->
436− return Set.empty
463+ do getVarNames arg
438− Error ->
466+ Structure EmptyRecord1 ->
439− return Set.empty
467+ return ()
469+ Structure (Record1 fields extension) ->
470+ do mapM_ getVarNames fields
471+ getVarNames extension
442−getVarNamesTerm :: Term1 Variable -> IO (Set.Set String)
443−getVarNamesTerm term =
444− let go = getVarNames in
447− Set.union <$> go a <*> go b
449− Fun1 a b ->
474+addVarName :: Int -> String -> Variable -> Flex -> Maybe Super -> TakenNames -> IO TakenNames
450− Set.union <$> go a <*> go b
475+addVarName index givenName var flex maybeSuper taken =
478+ makeIndexedName givenName index
480+ case Map.lookup name taken of
482+ do when (name /= givenName) $ UF.modifyDescriptor var $ \desc ->
483+ desc { _content = Var flex maybeSuper (Just name) }
484+ return $ Map.insert name var taken
452− EmptyRecord1 ->
486+ Just otherVar ->
453− return Set.empty
487+ do same <- UF.equivalent var otherVar
490+ else addVarName (index + 1) givenName var flex maybeSuper taken
455− Record1 fields extension ->
492+
456− do fieldVars <- Set.unions <$> mapM go (Map.elems fields)
493+makeIndexedName :: String -> Int -> String
457− Set.union fieldVars <$> go extension
494+makeIndexedName name index =
498+ else if Char.isDigit (last name) then
499+ name ++ '_' : show index