F#和继承的建模

F# and modeling of the inheritance

我的问题涉及到一种方法,如何以功能性的方式处理F中的继承。为了稍微描述一下,我举了一个简单的例子。假设我们想模拟一个由各种动物组成的世界。每种动物都与其他种类(如名称、大小等)共享一些属性。此外,每种动物都可能有其他动物,而其他动物不共享这些动物(例如,儿童的数量与狗和猫有关,但与蜘蛛无关)。此外,可能有与每种动物相关的方法或功能,对于两种动物可能相同,也可能不相同,即,有默认的实现,可能被某一特定类型所超越。每种动物都可能有仅为该类定义的方法。

现在,在OOP世界中,这可能会导致一个抽象类,它具有公共的属性和抽象方法,然后是为每种动物派生的类。我不确定的是如何在f_中功能性地指定域模型。在这里:在f中使用哪个抽象类或接口?据称,"惯用F代码使用不同于C的扩展点(例如,将函数/接口作为参数),因此您实际上不需要抽象类"。

如果这是一种应该采用的方法,是否可以提供一些基本的例子呢?

至于我对此的进一步思考,我认为应该将属性封装在某种结构中。然后,这方面最惯用的结构就是记录。这是否意味着要有一个父记录,它应包括在与特定"子"相对应的其他记录中,即组成而不是继承。然而,在我看来,这似乎是一个既不惯用也不特别优雅的解决方案。

我认为在F中如何建模继承的首选方法是歧视联合。但是,这并不能解决共享属性和方法的问题。

在我看来,与上面提到的模型类似的模型非常频繁,因为大多数企业应用程序中都隐式地包含了这些模型。因此,是否有任何关于如何以功能性方式处理这一问题的建议(以上述链接下建议的方式或任何其他建议为例)?或者我们应该说,这不是一个可以使用功能方法轻松建模的领域?

谢谢您。


您对示例的描述已经预先假定了面向对象的编程模型。您用面向对象的术语描述这个问题,例如覆盖和为某些类型的动物定义的方法。这使您很难给出一个明智的可选功能表示,因为您的问题在答案中已经假定了面向对象的概念。

首先,在f中使用面向对象的构造是非常好的,当它们有意义的时候(您问题中的示例只是一个玩具示例,所以可能是这样,也可能不是这样)。关键的想法是F更喜欢组合而不是继承,因此您可能会尝试避免继承(这会导致复杂的对象层次结构),而不是从不同的方面组合动物。

第二,如果你用不同的方式解释你的问题,那么使用歧视工会可能会有完美的功能表示。例如:

1
2
3
4
5
6
type MammalKind = Cat | Dog
type MammalInfo = { Legs : int; Children : int }

type Animal =
  | Mammal of MammalKind * MammalInfo
  | Spider of (...)

我们的想法是构建一个类型,让不同种类的动物(你可以用不同的方式处理)有自己的类型。例如,您可以编写一个函数来获取MammalInfo,并执行一些只对狗和猫有意义的计算(但对蜘蛛没有意义)。但是正如我前面提到的,您对问题的描述本质上是面向对象的,因此很难看到如何做到这一点。