2016-05-02 22 views
4

これはOCamlの中で型定義についてです、私は次の構文不可解を見つける:OCaml構文:タイプ 'a t mean?

​​

それは平易な英語では何を意味するのでしょうか?

+0

[Ocaml Variant Types]の可能な複製(http://stackoverflow.com/questions/4777744/ocaml-variant-types) – Laurel

答えて

4

OPはC++言語での経験があるので、以下の説明が参考になると思います。フォームの型宣言:

​​

は、'a listジェネリックリストたとえばC++

template <typename a> class t; 

に近接していて、'aは、要素のタイプです。簡潔にするため、template <typename _>の代わりに'という単一の文字を使用します。 OCamlの用語では、「ジェネリックプログラミング」の代わりに「パラメトリックポリモーフィズム」という用語を使用します。また、単語テンプレートの代わりに、型コンストラクタがあります。後者は興味深い結果をもたらします。 C++の場合と同様に、テンプレートインスタンス化では、OCamlでは多態型の型変数をコンサーセル化して新しい型を作成します。たとえば、int listfloat list(c.f.、list<int>float<list>)です。したがって、型コンストラクタ'a listを型レベルで単項関数として見ることができ、型を受け取り、型を作成します。例えば、type ('key, 'value) hashtblは、与えられたkeyvalueの組の型を作成するバイナリ型のコンストラクタであるような、nary型のコンストラクタを持つことが可能です。さらに、非パラメトリック型はnullary型のコンストラクタとして見ることができるので、intは型intを構築します。

P.S.OCamlの子孫であるF#言語は、両方の形式で書くことができます:int tt<int>

P.P.S混乱を避けるために、テンプレートとパラメトリックタイプは同じ問題を解決しようとしていますが、まだ違いはほとんどありません。テンプレートはインスタンス化の後にタイプされ、前にパラメトリックタイプが入力されます。だからパラメトリックタイプ'a tはすべて'aのためにと定義されています。タイプ変数が普遍的に定量化されていないタイプを作成したい場合は、別のメカニズム、つまりファンクションを使用することができます。テンプレートにも非常に近いですが、C++の概念であるタイププラス型の要件を受け入れます。概念はOCamlのモジュール型で具体化されています。したがって、ファンクタは実際にはモジュールを受け取り、モジュールを生成するため、モジュールレベルの関数です。

4

これはパラメトリック型宣言です。

型宣言は、新しいデータ型を宣言することができます。今で

type 'a container = 'a * string * 'a 

let x : int container = (0, "hello", 1) 
let y : string container = ("stack", "over", "flow") 

type my_type = int * string 

let x : my_type = (42,"Sorry for the inconvenience") 

は時々しかし、あなたはそれが引数として別の型を取る意味、タイプはパラメトリックになりたいですその場合、型宣言の後には等号はありません。その意味は、それがモジュールのstructure(のような、.mlファイルの上)または(.mli中など)signatureであるかのかどうかによって異なり

それが構造内にある場合、それは無いとタイプを宣言内部の価値。これは空の集合と同じくらい有用です(時にはそうですが、多くはありません)。ただし、署名内にある場合は、「パラメトリック定義がどこかに存在しますが、ここからは表示されません」という意味です。

これら二つのファイルa.mla.mliがあるとします

(* a.ml *) 
type 'a t = Nil | Cons of 'a * 'a t 

let empty = Nil 
let add x l = Cons (x,l) 

(* and so on... *) 

(* a.mli *) 

type 'a t 

val empty : 'a t 
val add : 'a -> 'a t -> 'at 

(* and so on... *) 

あなたがA.tタイプを操作したいあなたのプログラムの残りの部分では、あなただけemptyaddを通じてそうすることができます場合はその他の定義された関数を使用しますが、NilConsを直接使用することはできません。