2016-07-07 15 views
6

datatype宣言では、すべてのバリアントの型引数がすべてeqtypeである場合、標準MLは等価型を生成します。コンストラクタを隠さずにSML型がeqtypeにならないようにする

私は平等の独自の定義を提供し、独自のeqtypesとSMLルールの予期しない結果を(構築するユーザーの無力を嘆いいくつかの場所でのコメントを見てきた例裸ref sおよびarray sがeqtypesですが、datatype Foo = Foo of (real ref) eqtypeではありません)。

出典:http://mlton.org/PolymorphicEquality

1は、REF細胞上のポインタの比較が十分であるため、実際のタイプTの2つの値を比較することができることを期待するかもしれません。残念なことに、型システムは、ユーザー定義のデータ型が等しいかどうかを認識することしかできません。

ブロック eqtypingが可能かどうかは疑問です。例えば、私はバイナリツリー(不必要なバリアントを持つ)としてセットを実装しており、構造的にセットを互いに比較することを誓いたいとします。

datatype 'a set = EmptySet | SetLeaf of 'a | SetNode of 'a * 'a set * 'a set; 

は、それが抽象破り操作なので、私は人々が=SetLeaf(5)SetNode(5, EmptySet, EmptySet)を区別できるようにしたくないと言います。

datatype on = On | Offという単純な例を試してみましたが、シグネチャを使用してタイプを非eqtypeに降格できるかどうかを確認しました。

(* attempt to hide the "eq"-ness of eqtype *) 
signature S = sig 
    type on 
    val foo : on 
end 

(* opaque transcription to kill eqtypeness *) 
structure X :> S = struct 
    datatype on = On | Off 
    let foo = On 
end 

透明帰属がeqtypeになってからX.onを防ぐために失敗したようだが、不透明な帰属はそれを防ぐん。しかし、これらのソリューションは理想的ではありません。なぜなら、新しいモジュールを導入してデータコンストラクタを隠すからです。カスタムの型や型のコンストラクタがeqtypeになったり、データコンストラクタを隠さずに、あるいは新しいモジュールを導入したりせずに、等価性を認めないようにする方法はありますか?

答えて

6

短い答えはノーです。型の定義が見えるとき、その型の定義は何でも意味します。それがイコライズされないようにする唯一の方法は、たとえばrealパラメータを持つダミーのコンストラクタを追加するなどしないように定義を微調整することです。

Btw、小修正:あなたのタイプfooは等価タイプにする必要があります。 SMLの実装が不一致の場合、バグがあります。別のケースはreal barで、datatype 'a bar = Bar of 'a ref(これはMLtonのマニュアルで説明しています)です。最初のものは動作しますが、2番目のものが動作しないのは、refがSMLの魔法です。つまり、ユーザータイプには存在しない多相のeq-nessの形をしています。

+0

R.e.バーケース、私の間違い。 SML/NJはあなたが記述する 'データ型' bar caseを拒否しますが、データ型foo =(実際のref)のFooの場合、私は最初に 'polyEqual'を呼び出すという厄介な警告を出すだけでした。 –

関連する問題