SML 中具有有限数量类型 n > 1 的值
A value in SML which has a finite number of types n > 1
因此,问题是对于任何整数 n,是否存在恰好具有 n 种类型的值。
对于 n=0 和 n=1,答案应该很明确(零,很多),但是对于 n>1 呢?
For n=0, and n=1, the answer should be clear (zero, many).
But what for n > 1?
TL;DR: 对于某些 n,是的,但不是一般情况。
让我明白这些明确的答案是否是:
- n = 0:不,没有属于零类型的值。 (如果一个值存在,它必须有一个类型。值在定义它们的类型之前不存在于 SML 中。)
- n = 1: 是的,有一个值恰好属于一种类型。 (有无数种方法可以表达属于一种类型的值:
datatype one = One
、datatype two = One | Two
、datatype three = One | Two | Three
,在这种情况下,这些值构造函数中的任何一个都只属于一种类型任意一分。)
如果这不是对您问题的正确解释,您能否澄清和阐述问题以及这些明确的答案?继续假设这种解释是正确的,这里有一些关于 n > 1 的想法:
对于具有多种类型的值,该值必须是多态的。我可以想到两种方法:
对于“ad-hoc polymorphism”(又名重载):n = K:重载的一些有限示例,具有多种类型的内置运算符(例如 +
具有键入 int * int -> int
和 real * real -> real
,具体取决于它被推断为什么。)老实说,我不知道究竟有多少类型为它重载了 +
,但我可以看到它在至少 3 个:
- 1 + 1;
> val it = 2 : int
- 1.0 + 1.0;
> val it = 2.0 : real
- 0w1 + 0w1;
> val it = 0wx2 : word
所以对于任意的 K ≥ 3: 是的,op +
是一个恰好有 K 类型的值。
可能有多个具有不同类型数量的重载内置值,但由于重载内置运算符的数量是有限的,因此这只适用于极少数 n > 1,而不是一般情况下,对于所有 n > 1。
您可能会争辩说,这实际上是三个具有相同名称的不同 op +
值。它们的实现方式不同,行为也不同,因此可以合理地说它们不是相同的值,即使它们共享相同的名称。在这种严格的解释下,就只剩下参数多态了。
对于“parametric polymorphism”:值 []
的类型为 'a list
,但它也有类型 int list
、real list
, bool list
, 等等。我不知道你是否会说它有无限多种类型,但我想你可以这么说。但是,即使您确实这么说了, 'a something
类型的值也不会有有限数量的 n > 1 类型。 ('a, 'b) something
也不是这种情况,依此类推。
除了这两种多态性之外,我想不出其他方法让一个值在 SML 中具有不止一种类型。一个有趣的后续问题是,除了这两种方式之外,是否存在有意义的方式来定义具有 n > 1 的 n 类型的任何类型系统中的值。
如果问题是“对于 每个 整数 n ≥ 0,是否存在正好具有 n 的 type 值?"答案是“是”,因为对于 n = 1 你有 datatype One = One
,对于 n = 2 你有 datatype Two = One | Two
,等等。对于 n = 0,您可以构造一个没有公开构造函数的 abstract/opaque 类型。在 Haskell 中,此类型只是 data Void
,没有 = ...
部分,但在 SML 中缺少此语法,您可以执行以下操作:
signature VOID = sig type t end
structure Void :> VOID = struct type t = unit end
fun whyNot (x : Void.t) = "I wonder how one might call this function."
即使 Void.t
被定义为 unit
,它也是不透明的,隐藏了 ()
值构造函数:
- whyNot ();
! Toplevel input:
! whyNot ();
! ^^
! Type clash: expression of type
! unit
! cannot have type
! Void.t
因此 Void.t
和 unit
之间的等价性没有暴露,给类型 Void.t
0 个值。
这个问题的答案很简单:没有。
原因是标准 ML 基于具有推断类型的类型系统(特别是 Hindley Milner 类型系统)。在这个类型系统中,每个值都有一个多类型。你可能想考虑一个包含无限数量类型的多类型,例如 type: 'a -> 'a 包含很多类型,例如 int->int。在这种情况下,对于任何 HM 多类型,例如具有参数的类型,将有无限数量的类型,对于类型不是多类型的任何值,将有有限数量的类型,恰好是一个。
总结:ML 中的任何正确值都具有一种多类型,以及一种或无限多类型。
因此,问题是对于任何整数 n,是否存在恰好具有 n 种类型的值。 对于 n=0 和 n=1,答案应该很明确(零,很多),但是对于 n>1 呢?
For n=0, and n=1, the answer should be clear (zero, many).
But what for n > 1?
TL;DR: 对于某些 n,是的,但不是一般情况。
让我明白这些明确的答案是否是:
- n = 0:不,没有属于零类型的值。 (如果一个值存在,它必须有一个类型。值在定义它们的类型之前不存在于 SML 中。)
- n = 1: 是的,有一个值恰好属于一种类型。 (有无数种方法可以表达属于一种类型的值:
datatype one = One
、datatype two = One | Two
、datatype three = One | Two | Three
,在这种情况下,这些值构造函数中的任何一个都只属于一种类型任意一分。)
如果这不是对您问题的正确解释,您能否澄清和阐述问题以及这些明确的答案?继续假设这种解释是正确的,这里有一些关于 n > 1 的想法:
对于具有多种类型的值,该值必须是多态的。我可以想到两种方法:
对于“ad-hoc polymorphism”(又名重载):n = K:重载的一些有限示例,具有多种类型的内置运算符(例如
+
具有键入int * int -> int
和real * real -> real
,具体取决于它被推断为什么。)老实说,我不知道究竟有多少类型为它重载了+
,但我可以看到它在至少 3 个:- 1 + 1; > val it = 2 : int - 1.0 + 1.0; > val it = 2.0 : real - 0w1 + 0w1; > val it = 0wx2 : word
所以对于任意的 K ≥ 3: 是的,
op +
是一个恰好有 K 类型的值。可能有多个具有不同类型数量的重载内置值,但由于重载内置运算符的数量是有限的,因此这只适用于极少数 n > 1,而不是一般情况下,对于所有 n > 1。
您可能会争辩说,这实际上是三个具有相同名称的不同
op +
值。它们的实现方式不同,行为也不同,因此可以合理地说它们不是相同的值,即使它们共享相同的名称。在这种严格的解释下,就只剩下参数多态了。对于“parametric polymorphism”:值
[]
的类型为'a list
,但它也有类型int list
、real list
,bool list
, 等等。我不知道你是否会说它有无限多种类型,但我想你可以这么说。但是,即使您确实这么说了,'a something
类型的值也不会有有限数量的 n > 1 类型。('a, 'b) something
也不是这种情况,依此类推。
除了这两种多态性之外,我想不出其他方法让一个值在 SML 中具有不止一种类型。一个有趣的后续问题是,除了这两种方式之外,是否存在有意义的方式来定义具有 n > 1 的 n 类型的任何类型系统中的值。
如果问题是“对于 每个 整数 n ≥ 0,是否存在正好具有 n 的 type 值?"答案是“是”,因为对于 n = 1 你有 datatype One = One
,对于 n = 2 你有 datatype Two = One | Two
,等等。对于 n = 0,您可以构造一个没有公开构造函数的 abstract/opaque 类型。在 Haskell 中,此类型只是 data Void
,没有 = ...
部分,但在 SML 中缺少此语法,您可以执行以下操作:
signature VOID = sig type t end
structure Void :> VOID = struct type t = unit end
fun whyNot (x : Void.t) = "I wonder how one might call this function."
即使 Void.t
被定义为 unit
,它也是不透明的,隐藏了 ()
值构造函数:
- whyNot ();
! Toplevel input:
! whyNot ();
! ^^
! Type clash: expression of type
! unit
! cannot have type
! Void.t
因此 Void.t
和 unit
之间的等价性没有暴露,给类型 Void.t
0 个值。
这个问题的答案很简单:没有。
原因是标准 ML 基于具有推断类型的类型系统(特别是 Hindley Milner 类型系统)。在这个类型系统中,每个值都有一个多类型。你可能想考虑一个包含无限数量类型的多类型,例如 type: 'a -> 'a 包含很多类型,例如 int->int。在这种情况下,对于任何 HM 多类型,例如具有参数的类型,将有无限数量的类型,对于类型不是多类型的任何值,将有有限数量的类型,恰好是一个。
总结:ML 中的任何正确值都具有一种多类型,以及一种或无限多类型。