【问题标题】:Is allowing untagged unions equivalent to allowing type classes?允许未标记的联合是否等同于允许类型类?
【发布时间】:2016-11-19 16:01:22
【问题描述】:

this 问题中,未标记的联合被描述为子类型的一种形式。

类型类也是子类型的一种形式。

它们在概念上是否等效?他们是,我将如何在 Haskell 中实现这些?

【问题讨论】:

  • 我认为 Haskell 没有传统定义的子类型,因为每个值都只有 one 类型。类型类只是扩展类型语言以允许用户定义的多态性的一种方式。也就是说,它让值x 具有C a => a 类型,其中Ca 必须遵守的一组规则;但x 仍然只有一种类型。将此与 OOPy 子类型进行对比,其中值 x 具有多种类型:它的基本类型,以及从基本类型继承的任何类型。
  • 另一个更迂腐的论点:子类型会抑制 Haskell 编译器具有的 DHM 风格的主体类型类型推断,而类型类则没有。
  • 详细说明@haoformayor 的观点:不要混淆子类型和临时多态性。子类型是一种特殊的多态性,而类型类则完全不同。

标签: haskell type-theory subtyping


【解决方案1】:

类型类也是子类型的一种形式。

他们不是。为了便于说明,让我们回到我暗指in that questionTypeScript examples

如果我们有一个联合类型的值,我们只能访问成员 这对联合中的所有类型都是通用的。

interface Bird {
    fly();
    layEggs();
}

interface Fish {
    swim();
    layEggs();
}

function getSmallPet(): Fish | Bird {
    // ...
}

let pet = getSmallPet();
pet.layEggs(); // okay
pet.swim();    // errors

这里,getSmallPet 的返回类型既不是 Fish 也不是 Bird,而是两者的超类型,其成员为 FishBird 的共同成员。 Fish也是Fish | BirdBird也是。

类型类发生的情况完全不同:

foo :: Num a => a -> a
foo x = (x * x) + x

虽然foo (3 :: Integer)foo (7.7 :: Double) 都有效,但这并不意味着(3 :: Integer)(7.7 :: Double) 也有对应于Num 的超类型。相反,Num a => a -> a 所说的只是你选择的a 应该有一个Num 的实例(值得强调的是Num 不是一个类型),所以(*) 有合适的实现和(+) 用于您选择的类型。与 OOP 方法不同,(*)(+) 不属于任何特定类型,因此无需引入超类型即可将它们与 IntegerDouble 一起使用。

【讨论】:

  • 这个答案很有帮助,谢谢。尽管如此,我感觉这两个概念至少是相关的,因为Pet 示例也可以通过类型类来实现。表述为一个问题:“类型类约束是否与未标记的联合一样强大?” (尽管这可能更适合作为后续问题)。
  • @ThreeFx 我们可能会说,在这种情况下,它们将是实现同一目标的两种截然不同的方式。顺便说一句,值得注意的是,未标记的方面对于讨论不是必不可少的——如果在 TypeScript 示例中,我们有一个带有 layEggs 方法的 Oviparous 接口,FishBird 将扩展,根本区别将保持不变。一个相关的,如果有点切题,问题:Parametric polymorphism vs Ad-hoc polymorphism.
  • 包含与子类交互的方式非常类似于子类型。如果一个函数需要forall f. Applicative f => f a -> f b 类型的参数,我当然可以传递forall f. Functor f => f a -> f b 类型的参数之一。现在这确实超出了标准的 Haskell,但长期以来,高级类型一直是真正的 Haskell 的重要组成部分。
  • @dfeuer 确实——在考虑the lens hierarchy 时,我们明确谈论子类型并非没有理由。对此答案的后记将是值得补充的。
  • @duplode,顺便说一句,我昨天遇到了一些非常相关的事情,这让我意识到(也许是第一次)删除和重新应用 newtype 构造函数并不总是一个禁止-同上。请参阅this PR,它通过更改函数的约束来迭代地修改函数。特别是,WonkP (runWonkP w) 不是 coerce w
猜你喜欢
  • 1970-01-01
  • 2021-06-13
  • 2018-10-18
  • 2018-12-07
  • 1970-01-01
  • 2018-03-03
  • 2014-09-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多