I assume that your interpreter will work within the State
monad. Probably the state will consist of a collection of live objects and whatnot. What you can do, is keep track of a list of available (non-used) id
s (represented as Int
s) and annotate every Object
with an Int
, namely its id
. This id
was taken from the list of available id
s and assigned to it at creation time. Thus it cannot be that two Object
instances have the same id
.
Observe that I talked about Int
s. You could go for Integer
s, but that may eventually become less efficient. Going with Int
s does mean that you'll have to add the id
of destroyed objects back to the pool (list) of available id
s (for otherwise you'd run out, eventually). Thus I envision something like this:
data Object a = Obj Int a
instance Eq (Object a) where
Obj i _ == Obj j _ = i == j
type InterpreterState a = State [Int] a
createObject :: a -> InterpreterState (Object a)
createObject a = do
(i:is) <- get
put is
return $ Obj i a
destroyObject :: Object a -> InterpreterState ()
destroyObject (Obj i a) = do
modify (i:)
(Note that InterpreterState
will be much more complex in your case, and createObject
and destroyObject
should have the object added to/removed from the state. But that's beside the point here.)