如何在Haskell中模拟对象标识的概念

时间:2009-11-25 07:16:43

标签: python haskell interpreter

我正在考虑为Haskell中的面向对象语言设计Python解释器。我面临的一个特殊问题涉及对象身份的概念。如果我们考虑Python的id(object)函数,则定义表明它返回对象的“标识”。这是一个整数(或长整数),保证在该生命周期内该对象是唯一且恒定的。具有非重叠生存期的两个对象可以具有相同的id()值。 (实施说明:这是对象的地址。)

在Haskell中实现这样的概念的一般方法是什么?

2 个答案:

答案 0 :(得分:4)

我假设您的翻译将在State monad中工作。可能该州将包括一系列活动对象和诸如此类的东西。您可以做的是跟踪可用(未使用)id s(表示为Int s)的列表,并使用Object为每个Int添加注释,即它的id。此id取自可用id列表,并在创建时分配给它。因此,两个Object实例不能具有相同的id

观察我谈过Int。你可以去Integer,但最终可能效率降低。使用Int s确实意味着您必须将id个已销毁的对象添加回可用id的池(列表)中(否则您将耗尽,最终)。因此,我设想这样的事情:

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:)

(请注意InterpreterState在您的情况下要复杂得多,createObjectdestroyObject应该在状态中添加/删除对象。但这不是重点。)

答案 1 :(得分:3)

这个问题的答案取决于你将如何实现这些想要获取id的对象。如果两个变量包含相同的对象,它将如何看待?您基本上需要在变量中存储对“可变”对象的引用,问题是您是如何做到这一点的。如果你只是将简单值与变量名相关联,那么一个变量中的变化永远不会反映在另一个变量中,并且不存在对象标识这样的东西。

因此变量需要保持对对象的实际当前值的引用。这看起来像这样:

data VariableContent = Int | String | ObjRef Int | ...
data ObjStore = ObjStore [(Int, Object)]
data ProgramState = ProgramState ObjStore VariableStore ...

此处ObjRef每个ObjStore引用Int中可以通过ObjRef中存储的Int ID访问的值。这id(object)函数返回id是正确的。

通常,{{1}}函数很大程度上取决于您实际实现对象引用的方式。