是否有允许您对类型进行算术设置的编程语言?


9

出于好奇,是否存在允许您对类型进行设置算术以创建新类型的语言?就像是:

interface A {
  void a();
  void b();
}

interface B {
  void b();
  void c();
}

interface C = A & B; // has b()
interface D = A | B; // has a(), b() and c()
interface E = (A & B) ^ B; // has c()

我知道在某些语言中可以表达这些想法(即Java具有List<Comparable & Serializable>接口的统一性),但是我从未听说过支持类型算术的语言。谢谢!


7
这样的机制将如何有用?
罗伯特·哈维

4
我经常看到的一种模式是一个接口,该接口扩展了另外两个接口,并且不添加任何内容(即CanWriteAndCompare extends Serializable, Comparable {}),我在考虑如何对此进行概括。
Haldean Brown

2
另外,我今天遇到一种情况,其中我的方法可以采用a A或a B,并且两个实现看起来完全相同。在该方法中,我要调用可以采用A或的多态方法B,因此实现方式是相同的,但是由于必须采用两种不同的类型,因此需要两种实现方式。如果可以的话,这样会更容易myMethod(A | B aOrB)
Haldean Brown


1
Or可以通过多重继承来模拟操作。
用户

Answers:


4

切线0.3 spec)使用与此类似的东西。(免责声明:这是我自己的小研究项目)

with尽管实用主义使继承不具有可交换性,但目前充当联合运营商对继承进行建模。向方法介绍实现后,通常并不想严格地使用具有相同名称的方法进行联合,而且无论如何都无法正确执行。

intersect支持模型foo(T,T)对参数不同的内容进行类型推断。

补语很有趣,但是导致部分类型看起来似乎没什么用和/或很难正确地包含它们-因此不包含在内。

我知道我碰到过其他几种类似的研究语言,但目前还不记得他们。主要的问题是,如果没有结构化的类型,这些东西并没有真正的用处,这本身并不是很流行。另一个是您需要某种类型(类型的类型)来存储构造的类型,否则,这只是缺少该功能并不是特别习惯的事情的简写。这远没有结构类型化那么普遍。

这是有偏见的,虽然不多,但确实存在。


5

是的,锡兰语是一种具有临时联合和交集类型的语言,如锡兰之旅中本章所述:

http://ceylon-lang.org/documentation/1.0/tour/types/

您从中得到的很棒的成语令人惊讶。这是我最近写一个有趣的例子。这是一个简短的演示,在此我快速介绍了几个简单的习语

更好的是,联合/交叉点类型是“遗漏的链接”,使得通用类型参数推论在锡兰中确实适用,而与其他结合了子类型和参数多态性的语言相反。

请注意,正如您所描述的,这种“类型算术”存在局限性。例如,您不能在类型级别拥有集合补码运算符,至少在没有引入不确定性的情况下如此。

高温超导


3

Scala部分地支持它(交集而不是并集),并且任何具有结构子类型的语言(我认为OCaml就是一个例子)或一种足以模拟(Haskell是经典的)类型系统都将具有完整的“类型设置” ”功能,至少在其接受此类内容的类型系统的片段中(与在ala HList / OOHaskell中进行仿真时相关)。

由于我不太了解OCaml,因此我将给出您的示例在Scala中可用的部分:

trait A {
  def a(): Unit
  def b(): Unit
}

abstract class B { // just to prove it works with both traits and classes
  def b(): Unit
  def c(): Unit
}

type C = A with B
type D = { def b(): Unit } // not an exact translation, because unions aren't directly available
// type `E` is unrepresentable

Haskell的版本将取决于您使用的记录系统,并且可能会有些笨拙,因为它将被仿真而不是本机支持。

据我所知,锡兰在语言中完全内置了交集和并集类型,因此您可以根据它们对类型级别的“异或”进行编码。


1

Java在某些情况下支持接口类型的交集,尽管据我所知,它不支持创建交集类型的变量。交叉口类型可能会发挥作用,例如,在使用? :操作员时。如果该运算符的第二和第三操作数是不相关的接口,它们从重叠的接口集继承而来,则该运算符的结果将是这两者共同的接口集。


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.