![]() |
1
26
我认为ADT是继承的补充。这两种方法都允许您创建可扩展代码,但扩展性的工作方式不同:
面向对象世界和功能世界都开发了允许其他类型可扩展性的方法。在haskell中,你可以使用typeclasses,在ml/ocaml中,人们可以使用函数字典或者(?)函数来获取 内在风格 可扩展性。另一方面,在OOP中,人们使用访问者模式,这本质上是一种获得类似ADT的方法。 通常的编程模式在OOP和FP中是不同的,所以当您用函数语言编程时,您编写的代码需要 功能性风格 扩展性更常见(在OOP中也是如此)。在实践中,我认为有一种语言可以让你根据你要解决的问题使用这两种风格是很好的。 |
![]() |
2
9
托马斯佩特里切克的基本原理是完全正确的;你可能还想看看菲尔·韦德勒关于“表达问题”的文章。 我们中的一些人喜欢代数数据类型而不喜欢继承还有两个原因:
另外,你在读什么?我不知道有哪个负责人说“好;坏”。 |
![]() |
3
9
在我的经验中,人们通常认为大多数OO语言实现的继承“不好”,不是继承本身的概念,而是继承 子类修改在超类中定义的方法的行为 (方法覆盖) 特别是在可变状态下 . 这真的是最后一部分,这才是关键。大多数OO语言将对象视为“封装状态”,这相当于允许对象内部状态的急剧变化。因此,当一个超类期望某个方法修改一个私有变量,而一个子类重写该方法来做完全不同的事情时,就会出现问题。这可能会引入一些微妙的错误,而编译器对此无能为力。 注意,在Haskell的子类多态性实现中,不允许使用可变状态,因此您没有这样的问题。 此外,参见 this objection 子类型的概念。 |
![]() |
4
7
您描述的是闭和类型,这是代数数据类型最常见的形式,如f和haskell所示。基本上,每个人都同意在类型系统中它们是一个有用的特性,主要是因为模式匹配使得通过形状和内容来分解它们变得容易,而且还因为它们允许用尽性和冗余性检查。 然而,还有其他形式的代数数据类型。传统形式的一个重要限制是它们是封闭的,这意味着以前定义的闭和类型不能用新的类型构造函数扩展(更一般的问题称为“表达式问题”的一部分)。OCAML的多态变体允许开放和封闭的和类型,尤其是和类型的推理。相反,haskell和f_无法推断和类型。多态性变体解决了表达问题,它们非常有用。事实上,有些语言完全建立在可扩展代数数据类型上,而不是闭合和类型上。 在极端情况下,你也有类似Mathematica的语言,“一切都是一种表达”。因此,类型系统中唯一的类型形成了一个普通的“单例”代数。这是“可扩展的”,因为它是无限的,而且,它以完全不同的编程风格结束。
我相信您所指的是实现继承(即重写父类的功能),而不是接口继承(即实现一致的接口)。这是一个重要的区别。实现继承通常是不受欢迎的,而接口继承通常是受欢迎的(例如,在具有有限形式ADT的f中)。 您真的需要ADT和接口继承。像ocaml和f这样的语言可以同时提供这两种语言。 |
![]() |
Kon · OCaml中的模块类型语义 6 月前 |
![]() |
user20102550 · 如何在解析器中使用输入字符串 12 月前 |
![]() |
tijko · 处理整数数组时出现意外结果 1 年前 |
![]() |
David542 · 按列分区,按另一列排序 1 年前 |
|
Arnett Rufino · `max的输出是多少` 1 年前 |
![]() |
Adrian · 变量捕获:变量在函数闭包中的行为 1 年前 |