写完这段代码后
module type TS = sig
type +'a t
end
module T : TS = struct
type 'a t = {info : 'a list}
end
我意识到我需要info
是可变的。
我写道,然后:
module type TS = sig
type +'a t
end
module T : TS = struct
type 'a t = {mutable info : 'a list}
end
但是,令人惊讶的是,
Type declarations do not match:
type 'a t = { mutable info : 'a list; }
is not included in
type +'a t
Their variances do not agree.
哦,我记得听说过方差。这是关于协变和逆变的东西。我是一个勇敢的人,我会独自发现我的问题!
我可以写
module type TS = sig
type (-'a, +'b) t
end
module T : TS = struct
type ('a, 'b) t = 'a -> 'b
end
但后来我想知道。为什么可变数据类型是不变的而不仅仅是协变的?
我的意思是,我知道 an'A list
可以被视为 an 的子类型,('A | 'B) list
因为我的列表无法更改。函数也是一样,如果我有一个类型的函数,'A | 'B -> 'C
它可以被认为是类型函数的子类型,'A -> 'C | 'D
因为如果我的函数可以处理'A
并且'B
它只能处理'A
's,如果我只返回'C
's 我可以当然期望'C
或'D
's(但我只会得到'C
's)。
但是对于一个数组?如果我有 an'A array
我不能将其视为 an('A | 'B) array
因为如果我修改数组中的元素放入 a'B
那么我的数组类型是错误的,因为它确实是 an('A | 'B) array
而不再是 an 'A array
。但是 a('A | 'B) array
作为'A array
. 是的,这很奇怪,因为我的数组可以包含'B
但奇怪的是我认为它与函数相同。也许,最后,我并没有完全理解所有内容,但我想把我的想法放在这里,因为我花了很长时间才理解它。
TL;博士:
执着的 :
+'a
功能 :
-'a
可变:不变量(
'a
)?为什么我不能强迫它成为-'a
?