これを推測します記憶表現の質問ではありません。より一般的に型シグネチャに対する型宣言と一致する場合、または宣言t1
が宣言t2
未満一般的であるかどうかをチェックするときに、型チェッカーは、現在のみこれらの3つのケースを考える:
t2
は抽象型であるか、またはタイプ略語
t1
とt2
は、両方の和タイプ
t1
とt2
は両方のレコードがされている
他のケースでエラーが発生して失敗します。あなたの場合、t1
(チェックされているタイプ)はタイプの略語で、t2
(スペック)はサムタイプです。これは型エラーで失敗します。
ソースコード:type_declarations
をtyping/includemod.mlにしてください。
これは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
2つのタイプの 't'は同じですが、2つの' Foo'コンストラクタは同じではありません。これが正しければ、 'Foo'の矛盾する定義ほどパラメータ化された型をアンロールすることではないかもしれません。 –