{- | This is the start for an abstract data type 'Id'. We need @instance Eq Id@ and @instance Ord Id@. Furthermore an 'IdSupply'. However, currently 'Int' is used for that purpose and shall slowly be replaced by the new type 'Id'. Update: Slowly really doesn't cut it very well. Sometimes you have to just dive in and @newtype@, even if it *will* take days to fix the type errors. (This is a *slight* exaggeration...) Now Int has been replaced by the @newtype 'Id'@, but there are a few places on the frontier that don't really make any sense, such as in "ByteCode.Compiler" (Why were we passing 'Id's to 'ByteCode.Type.PUSH_ARG'?) and "RenameLib" (why are we passing them to 'TokenId.t_tuple'?) [SamB] -} module Id(Id, IdSupply(..), strId, strTVar) where import State newtype Id = Id Int deriving (Eq, Ord) instance Enum Id where toEnum n = Id n fromEnum (Id n) = n instance Show Id where show = strId -- | Convert an 'Id' to a string suitable for use as a variable name strId :: Id -> String strId (Id n) = show n strTVar :: Id -> String strTVar v = let v' = fromEnum v cv = toEnum (v' + fromEnum 'a') in if 'a' <= cv && cv <= 'z' then [cv] else toEnum (v'`mod`26 + fromEnum 'a'):'_':show (v'`div`26) -- else '_':show v -- | Whee! here goes to actually trying to *implement* @IdSupply@ ;-) -- -- At first I thought that because the the various pseudo-monads were -- just newtyped functions, I couldn't overload them... but then I -- realized that, since each is the same shape and has a different -- @FooState@ type, I could index them by that... anyway, here's to -- readable code that doesn't mix everything all together. -- [SamB] class IdSupply state where getUniqueId :: State a state Id state {- End Module Id ------------------------------------------------------------}