このコードを書いた後
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.
ああ、分散について聞いた覚えがあります。それは共分散と反分散に関するものでした。私は勇敢な人です、私は自分の問題を一人で見つけます!
この 2 つの興味深い記事 (こことここ) を見つけて、理解しました!
私は書くことができます
module type TS = sig
type (-'a, +'b) t
end
module T : TS = struct
type ('a, 'b) t = 'a -> 'b
end
しかし、私は疑問に思いました。変更可能なデータ型が共変ではなく不変なのはなぜですか?
つまり、私のリストは変更できないため、'A list
an は an のサブタイプと見なすことができることを理解しています。('A | 'B) list
関数についても同じことが言えます。タイプの関数がある場合、'A | 'B -> 'C
タイプの関数のサブタイプと見なすことができます。これは、関数がとを処理できる場合は のみを処理でき、 のみを返す場合は を処理できるためです。確かにまたはが期待されます(ただし、私はのみを取得します)。'A -> 'C | 'D
'A
'B
'A
'C
'C
'D
'C
しかし、配列の場合は?を持っている場合、それを anと'A array
見なすことはできません。('A | 'B) array
なぜなら、配列内の要素を変更して a を入れると'B
、配列型が間違っているからです。しかし、としてのa はどうでしょうか。はい、配列に含めることができるので奇妙ですが、奇妙なことに、関数と同じだと思いました。結局、すべてを理解できなかったかもしれませんが、理解するのに時間がかかったので、ここで考えを述べたいと思いました。('A | 'B) array
'A array
('A | 'B) array
'A array
'B
TL;DR :
持続的に :
+'a
機能 :
-'a
可変: 不変 (
'a
) ? 強制できないのはなぜ-'a
ですか?