问题标签 [subtyping]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
0 回答
51 浏览

c++ - 有效运行时定义类型的惯用语,互操作的域限制

严格来说,类型是 C++ 中的编译时构造。然而,有时对象的一些常量运行时特性被有效地定义为运行时类型。

例如,如果有一个几何向量,其中,由于框架限制,尺寸仅在运行时已知(否则我会将尺寸设为模板参数),例如从文件中读取。

维度是运行时这一事实并不意味着应该能够比较、分配或组合具有不同维度的向量。如果想在代码中引入这种逻辑,就必须限制一堆操作。这可以通过断言或抛出来完成,仅在运行时。

所以,例如,一个人会实现这个,

vec实施std::vector后尺寸不会改变。

这样做的问题是,最终会在所有函数中编写限制。

我的问题是,是否有任何习惯用法或工具可以通过限制(在运行时)使用不兼容对象执行的操作,特别是帮助编写更少重复的代码来帮助解决这个问题。

请注意,我不能使用std::array<double, 4>or3>因为4and3可能是运行时变量。

这个有效运行时类型的概念有名字吗?有没有被调查?


可能发生这种情况的其他示例:

1) 想象一下拥有可变大小的 NxN 数组并尝试定义数学加法。N 将是运行时的(甚至在构造后是常数),并且必须检查一个人没有添加不同大小的数组,还希望任何不兼容的比较都会触发错误。

2) 更一般地说,这个哲学问题可以出现在具有固定成员的类中。这有点做作,但假设一个人被迫拥有const成员

可以限制这一点:

我想象的唯一自动解决方案是系统地重载成员类型中的某些运算符(例如operator=() const)以强制执行此操作。

但是其中一个取决于(依赖)特殊成员类型,例如:

后来为了保持一致和系统,人们会写:

0 投票
2 回答
81 浏览

c++ - 具有不同子类型的参数化方法

今天在编程语言理论课中,我们在 Java 中看到了这种行为:

在主要:

其中“令人难以置信”的是,该方法必须在 Integer 和 Float 之间选择参数类型 Y,并选择最接近的超类型,即 Number。

我想在 C++ 中重现它,但我被卡住了......

0 投票
3 回答
266 浏览

scala - 如果存在子类型,Scala 中存在的用例是什么?

如果 Scala 也有子类型,那么 Scala 中存在存在主义有什么有意义的理由吗?

例如,在 Haskell 中,existentials 可以用于异构列表,但在 Scala 中,异构列表可以通过使用子类型来创建。

这让我想知道如果 Scala 中有子类型,为什么会有人想要使用存在主义?是否存在无法通过子类型更方便地解决的存在的用例?我不确定是否有。有反例吗?

编辑: Existentials 对于定义更高种类的类型(Functor、Monad 等)很有用,我理解,但除此之外,还有其他有意义的用例吗?

0 投票
4 回答
449 浏览

oop - Haskell:如何对不同但相关类型的列表进行处理?

我来自 OOP 背景,所以我无法理解这是如何在 Haskell 中完成的。

在 OOP 中,假设我们有Shape -> Circle, Rectangle, Square层次结构。我可以很容易地写出这个伪代码:

它会调用drawCircle、Rectangle、Square 的方法(或 Shape,如果它没有为子类型实现)。

如何在 Haskell 中实现这一点?

0 投票
2 回答
145 浏览

java - 使用子类型进行强制转换有哪些严格的“规则”?

我正在为即将到来的 Java 期末考试尝试一些练习考试,我遇到了这个问题。

考虑以下类定义并指出“Test.main()”是否会成功编译。如果它确实编译,表明它是否会成功运行,如果没有,表明会抛出什么异常。

我认为 Test.main() 会编译但会抛出运行时异常,因为 a 是实际的 C 类型,我们正试图将其转换为 B 类型。事实并非如此,因为答案说这很好。

我对铸造规则感到非常困惑,其中涉及的层次结构比 2 级更深。演讲幻灯片并没有这种信息!

那么,如果考试中出现此类问题,需要牢记哪些严格的“规则”?

0 投票
2 回答
543 浏览

scala - 带有子类型的scala中的联合类型:A | B <:A | B | C

我想要一个A|B类型作为A|B|C. 这可以在 Scala 中编码吗?如果是,如何?

我希望我可以在implicitly[¬¬[IF] <:< T]下面进行编译(这里的原始代码),但事实并非如此。有没有办法修复此代码以允许子类型化?

}

我也试过这个(从这里):

但在这里我不能将联合类型设为“一等”,它们只能作为参数类型存在,不能作为返回类型存在。

这种方法同样的问题:

0 投票
2 回答
194 浏览

haskell - 为什么通过存在和约束进行子类型化不起作用?

我一直在尝试了解 Haskell 如何处理子类型,所以我想出了以下代码片段:

该行f2 = f1失败并出现意外错误消息:

似乎存在主义被提升为普遍存在,这当然是无意的。

我的猜测是,在实现方面f2需要返回一个值和一个相应的字典,而f1只返回一个 type 的值Int。然而,从逻辑的角度来看,契约f2是“一个来自()某个未知实例的函数Integral”并且f1完美地满足了它。

GHC 应该做一些隐含的魔法来让它工作还是我错过了什么?

0 投票
2 回答
253 浏览

types - 在调用函数和回调之间对齐多态变体类型

我正在尝试编写一个不需要处理所有已知类型的事件的事件处理程序,并尝试使用 OCaml 多态变体类型(event.mli)对此进行建模:

一个示例实现(event.ml):

不幸的是,这失败并出现以下错误:

我怎样才能将实现mainLoop推断为 type ([< `click of int * int | `keypress of char | `quit of int ] -> unit) -> unit,即 as ('events event -> unit) -> unit

0 投票
1 回答
166 浏览

javascript - 流的信息丢失是否与这种多态性固有的结构子类型相关?

流中的结构子类型化可能会导致信息丢失:

(这段代码很糟糕,因为它执行可见的突变。它仅用于说明目的。)

我已经读过行多态性是一个在不危及类型安全的情况下避免这种信息丢失的概念。

有没有办法通过亚型多态性实现相同的目标?

[编辑]

为了让更多的观众看到,我对这个有点吓人的术语做一个简短的解释:

  • Polymorphishm只是一个花哨的词,用于确定两种类型是否等价,即它使刚性类型系统更加灵活
  • 参数多态性(流中的泛型)表明两种类型总是等价的,因为类型根本不重要
  • 子类型多态性(流中的子类型)表明,如果您可以从中派生层次结构,则两种类型是等价的,即将子类型包含在其超类型下
  • 行多态性类似于子类型,但解决了信息丢失问题(但是从技术上讲,不再存在子类型关系,因此它不是子类型的一种形式)
  • 有界多态性表明两种类型仅在特定目的下是等价的,例如相等、顺序、映射等。
0 投票
2 回答
180 浏览

types - 通配符模式覆盖多态变体的子类型约束

鉴于这些类型

和这个功能

正如预期的那样,应用类型的值a没有问题:

但是,如果修改函数以包含通配符模式

即使其他一切都保持不变,它现在会产生以下错误(on let _ = pp a):

此表达式的类型为 b -> 字符串,但预期的表达式类型为 a -> 'a Type b = [ `A | `B ] 与类型 a = [ `A ] 不兼容 第二个变体类型不允许标记 `B

问题:

  1. 为什么它不再能够接受子类型?我理解通配符意味着它现在可以接受超类型,但这不应该意味着它必须。
  2. 有没有办法解决这个问题,以避免枚举一百万左右不相关的变体?