これはメモリ表現の問題ではありません。型宣言を型シグネチャと照合する場合、またはより一般的には、宣言t1
が宣言より一般的でないかどうかをチェックする場合t2
、型チェッカーは現在、次の 3 つのケースのみを考慮します。
t2
抽象型または型の省略形です
t1
両方ともt2
和型
t1
t2
両方のレコード
他のケースはエラーで失敗します。あなたの場合、t1
(チェックされるタイプ)はタイプの略語であり、t2
(仕様)は合計タイプです。これは型エラーで失敗します。
ソース コードを参照しtype_declarations
てください。
foo.ml
これは、これでも失敗するため、メモリ表現の考慮事項ではありません。
type u = Foo of string
type t = u
おそらく、このチェックは洗練される可能性があります。バグトラッカーで質問する必要があります。
編集: このチェックをどこまで改善する必要があるかを判断するのは簡単ではありません。一般に、署名の一致をチェックするときに署名側で略語を展開することは正しくありません。たとえば、次のようなものは受け入れられません。
module Test : sig
type t = Foo
type u = t (* to the outside, t and u would be equal *)
end = struct
type t = Foo (* while internally they are different *)
type u = Foo (* sum/records are generative/nominative *)
end
逆の方法 (内部の平等が外部から隠されている) は正しく、すでに可能です。
module Test : sig
type t = Foo
type u = Foo
end = struct
type t = Foo
type u = t = Foo
end;;
fun (x : Test.t) -> (x : Test.u);;
(* Error: This expression has type Test.t but an expression
was expected of type Test.u *)
現在、型システムの動的セマンティクス (メモリ表現の選択) はそのような展開によって保持されないため、略語展開を検討するときにメモリ表現も考慮されます。
module Test : sig
type r = { x : float; y : float; z : float } (* boxed float record *)
end = struct
type 'a t = { x : 'a; y : 'a; z : 'a } (* polymorphic record *)
type r = float t
end