几个星期以来,我一直在思考对象之间的关系——尤其是 OOP 的对象。例如在C++中,我们习惯于通过在需要访问另一个对象的结构中分层指针或指针容器来表示。如果一个对象A
需要访问,在B
中找到一个并不少见。B *pB
A
但我不再是C++程序员,我使用函数式语言编写程序,尤其是在Haskell中,这是一种纯函数式语言。可以使用指针、引用或类似的东西,但我对此感到很奇怪,比如“以非 Haskell 方式进行操作”。
然后我对所有这些关系的东西进行了更深入的思考,并得出了结论:
“为什么我们还要用分层来表示这种关系?
我读到一些人已经考虑过(这里)。在我看来,通过显式图形表示关系要好得多,因为它使我们能够专注于我们类型的核心,然后通过组合器表达关系(有点像 SQL 所做的)。
我所说的核心是指当我们定义时,A
我们期望定义什么A
是由什么组成的,而不是它依赖什么。例如,在电子游戏中,如果我们有一个类型Character
,那么谈论它是合法的Trait
,Skill
或者诸如此类的东西,但是如果我们谈论Weapon
或者是Items
吗?我不再那么确定了。然后:
data Character = {
chSkills :: [Skill]
, chTraits :: [Traits]
, chName :: String
, chWeapon :: IORef Weapon -- or STRef, or whatever
, chItems :: IORef [Item] -- ditto
}
对我来说,在设计方面听起来确实是错误的。我宁愿喜欢这样的东西:
data Character = {
chSkills :: [Skill]
, chTraits :: [Traits]
, chName :: String
}
-- link our character to a Weapon using a Graph Character Weapon
-- link our character to Items using a Graph Character [Item] or that kind of stuff
此外,当有一天要添加新功能时,我们可以创建新类型、新图表和链接。在第一个设计中,我们必须打破Character
类型,或者使用某种变通方法来扩展它。
你怎么看这个想法?您认为在纯函数式语言Haskell中处理此类问题的最佳方法是什么?