1

Variant型を既存の異なる型の集合体として定義できるモジュール(Ocaml 3.12)を書きたいのですが

0からNのタイプである可能性があるため、変数リストまたはセット

それはこのように見えるかもしれません:

type newtype = Type0 of type0 | Type1 of type1 | ... | TypeN of typeN

もちろん、その作成を因数分解したい

最初に、ファンクターによってパラメーター化されたモジュール「Composite」を作成しようとしました。

module Composite ( T0 : sig type t end ) ( T1 : sig type t end ) = 
struct
  type t = T0.t | T1.t
end

最初の難しさ:ファンクターの変数リストを「コンポジット」モジュールに渡すにはどうすればよいですか?

これは続行するための良い方法ですか?

edit1:バリアントにより、XORタイプ定義を定義できます(T0またはT1のいずれかですが、両方ではありません)。ORタイプ定義(T0またはT1、あるいはその両方)を定義するにはどうすればよいですか?

4

2 に答える 2

5

「フラットな」複合型が必要でコンストラクターの和集合を取得する場合、唯一の方法は多態的なバリアントを使用することです(コメントの@lukstafiで述べられているように)が、この場合、t1とt2を抽象化することはできません。

type t1 = [ `A of int | `B of string | `C of float ]
type t2 = [ `B of string | `C of float | `D of char ]
type t3 = [ t1 | t2 ]

本当にモジュールを使用したい場合は、フラットな表現を失う必要があるため、非交和が発生します。

module Composite ( T0 : sig type t end ) ( T1 : sig type t end ) = 
struct
  type t = T0 of T0.t | T1 of T1.t
end
于 2012-04-30T08:12:35.327 に答える
1

静的型システムはあなたが望むものを許可しないと思います。静的型システムは、一部の関数で誤った型を使用することから生じるエラーを回避するのに役立ちます。しかし、ここでは、バリアントの*数*が不明なタイプを定義しようとしています。これはOCAMLではサポートされていません。

同じ理由で、異種リスト、および要素数が不明なタプルはサポートされていません。

2番目の質問に対して:オブジェクトは「T1とT2の両方」タイプにすることはできません。T1とT2は不明なタイプです...この概念は、タイプチェックと互換性がありません。T1とT2が互換性のあるタイプである場合、つまりT2がT1から継承されたオブジェクトタイプである場合、またはT2がT1の拡張であるポリモーフィックバリアントタイプである場合、タイプT1のオブジェクトを持つことができ、T2をT1にキャストすることもできます。 。しかし、それでも「T1とT2の両方」の概念はありません。T1のみを受け入れる関数がある場合、「T1」だけでなく「T1とT2の両方」タイプのオブジェクトが与えられた場合、この関数は何をすべきでしょうか。答えはないと思います。

これらはOCAMLではサポートされていませんが、OCAMLの型システムがコードを受け入れるように、おそらく別の方法で型を設計することができます。OCAMLの型システムは非常に柔軟性があり、コードのエラーを回避するのに役立ちます!

于 2012-04-30T08:55:40.583 に答える