【发布时间】:2021-06-05 05:18:48
【问题描述】:
所以我有一种自定义编程语言,并且我正在其中进行一些数学形式化/建模。在这种情况下,我基本上是这样做的(伪javascript表示):
isIntersection([1, 2, 3], [1, 2], [2, 3]) // => true
isIntersection([1, 2, 3], [1, 2, 3], [3, 4, 5]) // => false
function isIntersection(setTest, setA, setB) {
i = 0
while (i < setTest.length) {
let t = setTest[i]
if (includes(setA, t) || includes(setB, t)) {
i++
} else {
return false
}
}
return true
}
function includes(set, element) {
for (x in set) {
if (isEqual(element, x)) {
return true
}
}
return false
}
function isEqual(a, b) {
if (a is Set && b is Set) {
return isSetEqual(a, b)
} else if (a is X... && b is X...) {
return isX...Equal(a, b)
} ... {
...
}
}
function isSetEqual(a, b) {
i = 0
while (i < a.length) {
let x = a[i]
let y = b[i]
if (!isEqual(x, y)) {
return false
}
i++
}
return true
}
isIntersection 正在检查isEqual,isEqual 被配置为能够处理各种相等检查情况,从集合比较集合、对象到对象、X 到 X 等。
问题是,我们怎样才能让isEqual 不知何故对实现细节一无所知?现在,您必须为每种可能的对象类型设置一个大的 if/else/switch 语句。如果我们添加一个新类型,我们必须修改这个巨大的isEqual 方法来添加对它的支持。我们如何才能避免这种情况,而只需分别明确地定义它们?
我最初想用类方法使对象成为“类的实例”。但我喜欢让一切都只是函数和结构(没有方法的对象)的纯粹性。有没有什么方法可以在不使用带有方法的类的情况下实现这种事情,而只保留函数和对象?
如果不是,那么您将如何使用类来实现它?会是这样吗?
class Set {
isEqual(set) {
i = 0
while (i < this.length) {
let x = this[i]
let y = set[i]
if (!x.isEqual(y)) {
return false
}
i++
}
return true
}
}
这意味着每个对象都必须定义一个isEqual。 Haskell 如何处理这样的系统?基本上是在寻找如何最干净地完成这项工作的灵感。理想情况下,我希望避免使用带有方法的类。
注意:您不能只委托给 == 本地实现(就像假设这是在 JavaScript 中一样)。我们使用的是自定义编程语言,基本上是首先尝试定义== 的含义。
另一种方法是以某种方式传递isEqual 函数以及所有内容,尽管我真的不知道如何做到这一点,如果可能的话,它会很笨重。所以不确定最好的方法是什么。
【问题讨论】:
-
在 Haskell 中你有参数化,即你必须统一对待每一种类型。尽管参数化带有很好的属性,但它限制了你可以对类型做什么,因为你对它一无所知。类型类是一种让您了解类型或其在某些方面的行为方式的知识的方法。相等形成了这样一个类型类。我既不是类型理论家,也不是精通 Haskell,但我认为类型类是类型级别的第一个类名重载。这都是 Hindley-Milner 类型系统特有的,但可能对您没有多大帮助。
标签: oop functional-programming refactoring