2012-05-07 7 views
3

OCamlがシグネチャ内の中間的なパラメータ化された型をアンロールできない理由はありますか?例えばシグネチャに型パラメータを隠している

(* foo.ml *) 
type 'a internal = Foo of 'a 
type t = string internal 

と:

(* foo.mli *) 
type t = Foo of string 

がエラーを与えます。

は私が...これはメモリ表現は時々異なる可能性があるという事実にreleatedされていますが、OCamlのバグトラッカーにバグレポートを提出する前に、何らかの深い理由がある場合、私は思っていた

+0

2つのタイプの 't'は同じですが、2つの' Foo'コンストラクタは同じではありません。これが正しければ、 'Foo'の矛盾する定義ほどパラメータ化された型をアンロールすることではないかもしれません。 –

答えて

4

これを推測します記憶表現の質問ではありません。より一般的に型シグネチャに対する型宣言と一致する場合、または宣言t1が宣言t2未満一般的であるかどうかをチェックするときに、型チェッカーは、現在のみこれらの3つのケースを考える:

  • t2は抽象型であるか、またはタイプ略語
  • t1t2は、両方の和タイプ
  • t1t2は両方のレコードがされている

他のケースでエラーが発生して失敗します。あなたの場合、t1(チェックされているタイプ)はタイプの略語で、t2(スペック)はサムタイプです。これは型エラーで失敗します。

ソースコード:type_declarationstyping/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 
5

タイプが構造タイプである限り、それは可能です。:

type 'a t = 'a * int 
type u = string t 

はしかし、変異体(レコード)はOCamlの中名目種類がある

type u = string * int 

一致します。つまり、このような型の宣言はすべて、新しい型名を導入します。また、シグネチャ内の公称型指定は、公称型宣言によってのみ一致させることができ、同等の定義を持たなければなりません。あなたの例でもそうではないので、受け入れられません。 (。。これは、OCamlでの微妙なコーナーである構造型の別名と公称タイプの定義は、同じ構文を共有しているという事実は役立ちません)

FWIWは、あなたはまた、公称の種類を再バインドすることができます

type 'a t = Foo of 'a 
type 'a u = 'a t = Foo of 'a 

ます一致

type 'a u = Foo of 'a 

しかし、構造やパラメータを変更することはできませんので、あなたのケースを助けません。

関連する問題