社区首页 >问答首页 >Haskell中仿真对象的同一性

Haskell中仿真对象的同一性
EN

Stack Overflow用户
提问于 2013-10-07 08:09:49
回答 4查看 517关注 0票数 3

用面向对象的语言编写模拟,每个对象都有一个身份--也就是说,一种将其与模拟中的其他对象区分开来的方法,即使其他对象具有完全相同的属性。一个对象保留了它的身份,不管它随时间变化了多少。这是因为每个对象在内存中都有一个唯一的位置,我们可以用指针或引用来表示这个位置。即使您不强制使用像GUID这样的附加身份系统,这也是可行的。(您通常会这样做,以支持网络或数据库等不考虑指针的东西。)

我不相信在Haskell有一个类似的概念。那么,标准的方法是使用类似GUID的东西吗?

更新以澄清问题:标识是问题领域中的一个重要概念,原因之一是:对象之间存在关系,必须保留这些关系。例如,Haskell通常会说一辆红色的汽车就是一辆红色的汽车,而所有的红色汽车都是相同的(前提是颜色是汽车唯一的属性)。但是,如果每一辆红色汽车都必须与车主联系起来,该怎么办?如果车主能重新油漆他的车呢?

综合答案的最终更新:似乎一致认为,只有在模拟的某些部分实际使用这些标识符时,才应该向数据类型添加标识符,而且没有其他方法来表示相同的信息。例如,当一个人拥有多辆汽车,其中每一辆都有一个颜色,一个人可以保留一个不变的汽车列表。这充分表达了所有权关系,只要你能接触到那个人。

该人可能需要也可能不需要某种独特的标识符。出现这种情况的一个场景是:有一个函数可以接收一个汽车和一个集合的所有人员,并将一个ParkingTicket强加给合适的人。这辆车的颜色不能唯一地识别得到罚单的人。这样我们就可以给那个人一个身份证让他把车藏起来。

但即使是这样,也有可能通过更好的设计来避免。也许我们的汽车现在有了一个ParkingPosition类型的附加属性,它可以被评估为合法或非法。因此,我们将Person集合传递给一个函数,该函数查看每个人的汽车列表,检查每个人的ParkingPosition,并在适当的情况下将ParkingTicket强加给此人。因为这个函数总是知道它在看哪个人,所以没有必要让汽车记录这个信息。

因此,在许多情况下,分配it并不像最初看起来的那样必要。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2013-10-07 09:00:02

你为什么要“解决”这个非问题?对象标识是OO语言中的一个问题,Haskell很高兴地避免了这个问题。

在一个不可变对象的世界中,两个值相同的对象是同一个对象。将相同的不可变对象两次放入列表中,那么无论您想要看到什么地方,都有两个不同的对象(例如,它们都“都”贡献了元素的总数,并且它们具有唯一的索引),而没有Java风格的引用等式引起的任何问题。如果您愿意,甚至可以将该列表保存到数据库表中,并获取两个不同的行。你还需要什么?

更新

Jarret,您似乎确信模型中的对象必须具有真正独立的身份,因为现实生活中的对象是不同的。然而,在模拟中,这只在需要区分对象的上下文中起作用。通常,您只需要在必须区分和跟踪对象的上下文中使用唯一标识符,而不是在这些上下文之外。因此,确定这些上下文,映射对您的模拟(而不是对“真实”世界)重要的对象的生命周期,并创建适当的标识符。

你一直在回答你自己的问题。如果汽车有车主,那么鲍勃的红色汽车可以与卡罗尔的红色汽车区分开来。如果鲍勃能重新油漆他的汽车,你可以用一辆蓝色的汽车代替他的红色汽车。你只需要在

  1. 你的模拟有没有车主的汽车
  2. 你需要能够区分一辆没有主人的红色汽车和另一辆。

在一个简单的模型中,1可能是真,2不是。在这种情况下,所有无主的红色汽车都是同一辆红色汽车,那么为什么要把它们区分开来呢?

在你的导弹模拟中,为什么导弹需要跟踪他们自己的发射器?他们不是针对他们的发射器!如果发射器能够在导弹发射后继续控制导弹,那么发射器需要知道它拥有哪些导弹,但事实并非如此。导弹只需要知道它的弹道和目标。当它着陆和爆炸时,业主的意义是什么?如果它是从发射器A发射的,而不是从B发射器发射的,它会产生更大的爆炸吗?

你的发射器可以是空的,也可以有n导弹仍然可以发射。它有个位置。目标有位置。在任何时候都有k导弹在飞行,每一枚导弹都有一个位置、一个速度/弹道和一个爆炸威力。任何位置与地面重合的导弹,应转化为爆炸导弹或哑弹等。

在每一种情况下,哪些信息是重要的?发射装置的身份在引爆时真的很重要吗?为什么?敌人要发动报复性打击吗?不是吗?那这不是引爆的重要信息。它可能在发射后甚至都不是重要的信息。发射可以只是一个步骤,即A发射器所属的导弹数量减少,而飞行中的导弹数量增加。

现在,您可能对这些问题有了一个很好的答案,但是在开始使用对象可能不需要的标识之前,您应该完全映射您的模型。

票数 3
EN

Stack Overflow用户

发布于 2013-10-07 08:24:01

我的方法是将所有状态信息存储在数据记录中,如

代码语言:javascript
代码运行次数:0
复制
data ObjState = ObjState
    { objStName :: String
    , objStPos :: (Int, Int)
    , objStSize :: (Int, Int)
    } deriving (Eq, Show)

data Obj = Obj
    { objId :: Int
    , objState :: ObjState
    } deriving (Show)

instance Eq Obj where
    obj1 == obj2 = objId obj1 == objId obj2

并且状态应该由API/库/应用程序管理。如果您需要指向可变结构的真正指针,那么它就有内置的库,但是它们被认为是不安全和危险的,除非您知道自己在做什么(即使这样,您也必须小心)。有关更多信息,请查看base中的base模块。

票数 3
EN

Stack Overflow用户

发布于 2013-10-07 09:05:22

在Haskell中,值和恒等的概念是解耦的。所有变量都是与值的不可变绑定。

有几种类型的值是对另一个值的可变引用,如IORefMVarTVar,这些类型可以用作标识。

您可以通过比较两个MVar和比较它们引用的值来执行身份检查。

Rich的精彩演讲详细讨论了这个问题:http://www.infoq.com/presentations/Value-Values

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/19229586

复制
相关文章
Python 代码风格指南谷歌版
非常感谢我们的忠实读者 shendeguize,在后台留言告诉我,已经翻译了《谷歌Python代码风格指南》 ,大家这样相互帮助,感觉真是太好。
double
2020/05/08
1.2K0
Python 代码风格指南谷歌版
Python 代码风格指南谷歌版
https://github.com/shendeguize/GooglePythonStyleGuideCN
龙哥
2020/05/05
1.3K0
分享Google C++风格指南
  Qt君为大家收集的Google C++风格指南PDF版本(可能并不是最新版本) 。
Qt君
2020/05/08
4940
分享Google C++风格指南
Google C++ 编程风格指南:注释
注释虽然写起来很痛苦, 但对保证代码可读性至关重要. 下面的规则描述了如何注释以及在哪儿注释. 当然也要记住: 注释固然很重要, 但最好的代码本身应该是自文档化. 有意义的类型名和变量名, 要远胜过要用注释解释的含糊不清的名字.
CPP开发前沿
2022/03/03
8540
谷歌Python代码风格指南,翻译版来了!
非常感谢我们的忠实读者 shendeguize,在后台留言告诉我,已经翻译了《谷歌Python代码风格指南》 ,大家这样相互帮助,感觉真是太好了。
程序员小猿
2021/01/19
1.5K0
谷歌Python代码风格指南,翻译版来了!
Google C++ 风格指南 - 中文版 [值得收藏]
http://yangyubo.com/google-cpp-styleguide/ 很实用的手册,感觉象是effective c++,但其中明确指出了一些在开发过程中应该尽力避免的特性与用法,完全基于经验判定,更加简练! 每一章后面还有译者的笔记,进行了总结! 1.代码小于10行时使用inline 2.private拷贝构造函数,尽量不重载运算符 3.少用继承,看是否能用组合代替
王亚昌
2018/08/03
3140
Google C++ 编程风格指南(三):类
类是 C++ 中代码的基本单元. 显然, 它们被广泛使用. 本节列举了在写一个类时的主要注意事项.
CPP开发前沿
2022/03/03
8320
Google C++ 编程风格指南:头文件
所有头文件要能够自给自足。换言之,用户和重构工具不需要为特别场合而包含额外的头文件。详言之,一个头文件要有 1.2. #define 保护,统统包含它所需要的其它头文件,也不要求定义任何特别 symbols.
CPP开发前沿
2022/03/03
7980
Google C++ 编程风格指南(八):格式
代码风格和格式确实比较随意, 但一个项目中所有人遵循同一风格是非常容易的. 个体未必同意下述每一处格式规则, 但整个项目服从统一的编程风格是很重要的, 只有这样才能让所有人能很轻松的阅读和理解代码.
CPP开发前沿
2022/03/03
1.7K0
JavaScript 风格指南 [每日前端夜话(0x1C)]
原文链接:https://github.com/ryanmcdermott/clean-code-javascript
疯狂的技术宅
2019/03/27
8710
JavaScript 风格指南 [每日前端夜话(0x1C)]
TensorFlow风格指南
片刻
2018/01/05
8330
Google C++ 编程风格指南(二):作用域
虽然类已经提供了(可嵌套的)命名轴线 (YuleFox 注: 将命名分割在不同类的作用域内), 名字空间在这基础上又封装了一层.
CPP开发前沿
2022/03/03
7910
Google C++ 编程风格指南(六):命名约定
最重要的一致性规则是命名管理. 命名风格快速获知名字代表是什么东东: 类型? 变量? 函数? 常量? 宏 … ? 甚至不需要去查找类型声明. 我们大脑中的模式匹配引擎可以非常可靠的处理这些命名规则.
CPP开发前沿
2022/03/03
1.8K0
Google C++ 编程风格指南(五):其他 C++ 特性
总之大多时候输入形参往往是 const T&. 若用 const T* 说明输入另有处理。所以若您要用 const T*, 则应有理有据,否则会害得读者误解。
CPP开发前沿
2022/03/03
1.2K0
Pointfree 编程风格指南
本文要回答一个很重要的问题:函数式编程有什么用? 目前,主流的编程语言都不是函数式的,已经能够满足需求。为何还要学函数式编程呢,只为了多理解一些新奇的概念? 一个网友说: "函数式编程有什么优势呢?
ruanyf
2018/04/12
8980
Pointfree 编程风格指南
[译] Google Go 风格指南
以下几条总体原则总结了如何编写可读的 Go 代码。以下为具有可读性的代码特征,按重要性排序:
pseudoyu
2023/04/11
2920
Airbnb React/JSX 风格指南
// bad <div accessKey="h" /> // good <div />
ConardLi
2019/05/23
1.4K0
flutter代码风格指南
•UpperCamelCase 每个单词的首字母都大写,包含第一个单词•lowerCamelCase 每个单词的首字母都大写,除了第一个单词, 第一个单词首字母小写,即使是缩略词•lowercase_with_underscores 只是用小写字母单词,即使是缩略词, 并且单词之间使用 _ 连接
用户1974410
2022/08/07
1.2K0
Google C++编程风格指南(四)之类的相关规范
类是C++中基本的代码单元,自然被广泛使用。本节列举了在写一个类时要做什么、不要做什么。
恋喵大鲤鱼
2018/08/03
8790
Google C++ 编程风格指南(四):来自 Google 的奇技
Google 用了很多自己实现的技巧 / 工具使 C++ 代码更加健壮, 我们使用 C++ 的方式可能和你在其它地方见到的有所不同.
CPP开发前沿
2022/03/03
7220

相似问题

谷歌C++风格指南的AStyle

14

谷歌C++风格指南包括订单

21

谷歌风格指南(前降部分)

20

示例代码与示例的C++谷歌风格指南?

24

C++操作符重载,了解谷歌风格指南

30
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档