变体[`A | `B]
与[`A | `B | `C]
我知道他们无法统一,除非>
被添加到子集或<
添加到超集,但我很好奇是否有一个示例接受这种类型的输入可能导致错误的程序。
用这样一个非常简单的用法:
let return_a : bool -> [ `A ] = fun _ -> `A
let foo : bool -> [ `A | `B ] = return_a
接受实现似乎是完全安全的,因为foo
的声明类型是实现类型(return_a
的类型)的严格超集。但是(如预期的那样)它不会输入检查:
Error: This expression has type bool -> [ `A ]
but an expression was expected of type bool -> [ `A | `B ]
The first variant type does not allow tag(s) `B
实际上它看起来比
更具限制性let return_a : bool -> [ `A ] = fun _ -> `A
let foo : bool -> [< `A | `B ] = return_a
哪种类型检查。
这种对多态变体使用的限制只是对类型推断如何工作的限制,还是有一个实际的理由将第一个片段标记为错误类型?
答案 0 :(得分:4)
类型[`A | `B]
是[`A | `B | `C]
的子类型。 OCaml支持子类型,但它必须是显式的。
# type abc = [`A | `B | `C];;
type abc = [ `A | `B | `C ]
# type ab = [`A | `B];;
type ab = [ `A | `B ]
# let f (x: abc) = 14;;
val f : abc -> int = <fun>
# let (x: ab) = `A;;
val x : ab = `A
# f x;;
Error: This expression has type ab but an expression was expected of type abc
The first variant type does not allow tag(s) `C
# f (x :> abc);;
- : int = 14
#