@@ -1,7 +1,7 @@
1{-# OPTIONS_GHC -Wall #-}
1{-# OPTIONS_GHC -Wall #-}
2module Type.Type where
2module Type.Type where
4−import Control.Monad.State (StateT)
4+import Control.Monad.State (StateT, liftIO)
5import qualified Control.Monad.State as State
5import qualified Control.Monad.State as State
6import qualified Data.List as List
6import qualified Data.List as List
7import qualified Data.Map as Map
7import qualified Data.Map as Map
@@ -108,6 +108,16 @@ initialMark :: Int
108initialMark = 1
108initialMark = 1
116+getVarNamesMark :: Int
112-- CONSTRAINTS
122-- CONSTRAINTS
@@ -255,30 +265,43 @@ toSrcType variable =
256variableToSrcType :: Variable -> StateT NameState IO T.Canonical
266variableToSrcType :: Variable -> StateT NameState IO T.Canonical
257variableToSrcType variable =
267variableToSrcType variable =
258− do descriptor <- State.liftIO (UF.descriptor variable)
268+ do descriptor <- liftIO $ UF.descriptor variable
269+ if _mark descriptor == occursMark
274+ do liftIO $ UF.setDescriptor variable (descriptor { _mark = occursMark })
259− case _content descriptor of
275+ srcType <- contentToSrcType variable (_content descriptor)
260− Structure term ->
276+ liftIO $ UF.setDescriptor variable descriptor
261− termToSrcType term
277+ return srcType
263− Atom name ->
280+contentToSrcType :: Variable -> Content -> StateT NameState IO T.Canonical
264− return (T.Type name)
281+contentToSrcType variable content =
266− Var _ _ (Just name) ->
286+ Atom name ->
267− return (T.Var name)
287+ return (T.Type name)
269− Var flex maybeSuper Nothing ->
289+ Var _ _ (Just name) ->
270− do freshName <- getFreshName maybeSuper
271− State.liftIO $ UF.modifyDescriptor variable $ \desc ->
272− desc { _content = Var flex maybeSuper (Just freshName) }
273− return (T.Var freshName)
290+ return (T.Var name)
275− Alias name args realVariable ->
292+ Var flex maybeSuper Nothing ->
276− do srcArgs <- mapM (\(arg,tvar) -> (,) arg <$> variableToSrcType tvar) args
293+ do freshName <- getFreshName maybeSuper
277− srcType <- variableToSrcType realVariable
294+ liftIO $ UF.modifyDescriptor variable $ \desc ->
278− return (T.Aliased name srcArgs (T.Filled srcType))
295+ desc { _content = Var flex maybeSuper (Just freshName) }
296+ return (T.Var freshName)
298+ Alias name args realVariable ->
299+ do srcArgs <- mapM (\(arg,tvar) -> (,) arg <$> variableToSrcType tvar) args
300+ srcType <- variableToSrcType realVariable
301+ return (T.Aliased name srcArgs (T.Filled srcType))
280− Error ->
303+ Error ->
281− return (T.Var "?")
304+ return (T.Var "?")
284termToSrcType :: Term1 Variable -> StateT NameState IO T.Canonical
307termToSrcType :: Term1 Variable -> StateT NameState IO T.Canonical
@@ -381,28 +404,38 @@ getFreshName maybeSuper =
381getVarNames :: Variable -> IO (Set.Set String)
404getVarNames :: Variable -> IO (Set.Set String)
382getVarNames var =
405getVarNames var =
383 do desc <- UF.descriptor var
406 do desc <- UF.descriptor var
407+ if _mark desc == getVarNamesMark
412+ do UF.setDescriptor var (desc { _mark = getVarNamesMark })
413+ getVarNamesHelp (_content desc)
385− case _content desc of
416+getVarNamesHelp :: Content -> IO (Set.Set String)
417+getVarNamesHelp content =
386− Var _ _ (Just name) ->
419+ Var _ _ (Just name) ->
387− return (Set.singleton name)
420+ return (Set.singleton name)
389− Var _ _ Nothing ->
422+ Var _ _ Nothing ->
390− return Set.empty
423+ return Set.empty
392− Structure term ->
425+ Structure term ->
393− getVarNamesTerm term
426+ getVarNamesTerm term
395− Alias _name args realVar ->
428+ Alias _name args realVar ->
396− do let argSet = Set.fromList (map fst args)
429+ do let argSet = Set.fromList (map fst args)
397− realSet <- getVarNames realVar
430+ realSet <- getVarNames realVar
398− sets <- mapM (getVarNames . snd) args
431+ sets <- mapM (getVarNames . snd) args
399− return (Set.unions (realSet : argSet : sets))
432+ return (Set.unions (realSet : argSet : sets))
401− Atom _ ->
434+ Atom _ ->
402− return Set.empty
435+ return Set.empty
404− Error ->
437+ Error ->
405− return Set.empty
438+ return Set.empty
408getVarNamesTerm :: Term1 Variable -> IO (Set.Set String)
441getVarNamesTerm :: Term1 Variable -> IO (Set.Set String)