我正在玩这段代码,但我不明白。
type t1 = [ `A ];;
type t2 = [ t1 | `B ] ;;
type t3 = [ t2 | `C ] ;;
module type MT =
sig
type ('a,'b) fct
val create : ('a -> 'b) -> ('a,'b) fct
end;;
module Mt : MT =
struct
type ('a,'b) fct = 'a -> 'b
let create f = f
end;;
let f = (fun x -> x : t2 -> t2) ;;
let af = Mt.create (fun x -> x : t2 -> t2);;
(f :> t1 -> t3);;
(af :> (t1, t3) Mt.fct);;
像这样它不起作用,因为编译器不知道 Mt.fct 的类型参数是协变的还是逆变的。但是,如果您将模块签名中的类型声明替换为:
type (-'a,'+b) fct
告诉编译器 b 是协变和逆变的,现在它可以工作了。而且因为我是一个棘手的小烦人的男孩,我试图通过告诉编译器 a 也是协变的来欺骗编译器!
type (+'a,'+b) fct
他虽然比我聪明,但他注意到我在对他撒谎。
Type declarations do not match:
type ('a, 'b) fct = 'a -> 'b
is not included in
type (+'a, +'b) fct
Their variances do not agree.
我的问题是:如果他无论如何都知道类型参数的差异,为什么不将它用于我的模块,而不是强迫我添加那些 + 和 -。这又是一个可判定性问题吗?