代码之家  ›  专栏  ›  技术社区  ›  Shailesh Kumar

如何模拟haskell中的对象身份概念

  •  0
  • Shailesh Kumar  · 技术社区  · 15 年前

    我正在考虑在Haskell中为类Python的面向对象语言设计一个解释器。我面临的一个特殊问题是与对象身份的概念有关。如果我们考虑python的 id(object) 函数的定义建议它返回对象的“标识”。这是一个整数(或长整数),它保证在该对象的生存期内是唯一的和常量。生命周期不重叠的两个对象可能具有相同的id()值。(实现说明:这是对象的地址。)

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

    2 回复  |  直到 15 年前
        1
  •  4
  •   Stephan202 Alex Martelli    15 年前

    我想你的翻译会在 State 单子。可能这个州将由一个活的物体和其他东西的集合组成。你所能做的是跟踪可用(未使用)的列表 id S(表示为 Int s)并注释 Object 用一个 ,即其 身份证件 . 这个 身份证件 从可用的列表中 身份证件 并在创建时分配给它。所以不能是那两个 对象 实例具有相同的 身份证件

    int 你可以去 Integer 但这最终可能会降低效率。随同 int S表示您必须添加 身份证件 将销毁的对象返回到可用的池(列表) 身份证件 S(否则你最终会精疲力竭)。因此我设想如下:

    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 在你的情况下会更复杂,而且 createObject destroyObject 应将对象添加到状态或从状态中删除。但这不是重点。)

        2
  •  3
  •   sth    15 年前

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

    所以变量需要保存对对象实际当前值的引用。可能如下所示:

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

    这里每个 ObjRef 引用中的值 ObjStore 可以通过 Int 存储在 对象引用 . 而这 int 将是正确的东西被返回 id(object) 功能。

    一般来说 id 函数很大程度上取决于您实际如何实现对象引用。