language-agnostic - 是否可以统一继承和参数多态的概念?

标签 language-agnostic programming-languages types polymorphism variance

我想知道是否通常可以统一继承和参数多态性(“泛型”)的概念,特别是关于方差,还有他们必须如何(“语法”)和在哪里(使用站点/声明站点)被定义?

考虑这个观点:

  • 子类型 e. G。 S <: T可以被视为协变行为,因为输入参数接受 T也将接受S .
  • 将“继承模型的方差”更改为不变只能在定义端通过禁止子类型(例如,将 final 修饰符添加到类定义),就我所见,逆变是不可能的大多数情况
  • 默认情况下,参数多态性是不变的,但可以设为协变/逆变

  • 考虑到两者之间似乎存在不可忽略的概念不匹配
  • 语言因允许“不安全”协变而产生的痛苦(例如 Java/C# 中的 String[] <: Object[])
  • 与继承相比,继承/参数多态的声明和使用方式的差异

  • 在某些语言中,可以看出两者可以很好地协同工作,例如
    class Foo extends Ordered[Foo]
    

    实现排序/比较行为。
  • 是否可以想象继承和参数多态的概念可以统一并获得相同的默认方差行为(例如默认情况下协方差或会导致需要用不变注释标记大多数类型,因此只是将丑陋移到另一个点)?这是否更实用,好像数据结构默认情况下也会变得不可变一样?
  • 是否有一个正式的系统可以证明这是合理的?
  • 无论具体的编程语言如何,哪些语法选项/更改最有可能是必要的?
  • 是否有一些工作示例或语言已经在使用这种/类似的东西?
  • 最佳答案

    通过协方差/逆变,通常意味着这一点。假设 X , Y , Z是类型。进一步假设 a → b表示参数类型为 a 的函数类型和类型 b 的结果. <:表示子类型关系,或者可能是“一致性”的其他一些概念。 ⇒ 箭头读作“包含”。那么以下成立:

    X <: Y ⇒ (Z → X) <: (Z → Y)
    X <: Y ⇒ (Y → Z) <: (X → Z)
    

    也就是说,函数类型构造函数对于结果类型(数据源)是协变的,对于参数类型(数据接收器)是逆变的。这是一个基本事实,您或多或少不能对此做任何太有创意的事情,例如反转箭头的方向。当然,您始终可以使用无方差代替协变或逆变(大多数语言都这样做)。

    对象类型可以用函数类型进行规范编码,所以这里也没有太多的自由。每个类型参数表示数据源(协变)或数据接收器(逆变)或两者(变变)。如果它在一种语言中是合理且逆变的,那么在另一种语言中它要么是逆变的要么是不合理的。

    我认为 Scala 在这方面非常接近理想的语言。您引用了一个看起来很像 Scala 的示例,因此您很可能熟悉该语言。我想知道为什么你认为它的类型系统只在某些情况下才能很好地工作。其他情况是什么?

    每个有抱负的语言设计师都应该阅读的一本理论著作是 Luca Cardelli 的“对象理论”。

    关于language-agnostic - 是否可以统一继承和参数多态的概念?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6731855/

    相关文章:

    algorithm - 选择随机元素的数据结构?

    oop - 为什么类型推断对于面向对象的语言不切实际?

    programming-languages - 什么时候计算或变量读取更快?

    class - 如何在编译时获取单例对象的类?

    haskell - IO() 递归类型匹配问题

    language-agnostic - 获取随机地名和人名列表

    algorithm - 解决问题的动态规划技术

    c - C中各种const声明的区别

    python - 检查构造函数参数有效性的 pythonic 方法是什么?

    javascript - Record<string,any> 和 {} 之间的区别?