7.13 型変数の命名

(OCaml 3.12 〜)

parameter ::= ...
| ( type typeconstr-name )

fun ( type typeconstr-name ) -> exprexpr のスコープに typeconstr-name という型構成子を導入します。この構成子はスコープ内では抽象として扱われますが、それ以降では新しい型変数に置き換えられます。構文とは対照的に fun ( type typeconstr-name ) -> expr 自体は、通常の抽象とは異なり、 expr の評価を中断しません。この構文は、一般的な用法であるところの、関数の宣言の文脈に合うように選ばれました。次のように、通常の関数の引数と疑似型パラメータを自由は自由に混ぜることができます。

let f = fun (type t) (foo : t list) -> ...

関数宣言の代替構文でも使うことができます。

let f (type t) (foo : t list) = ...

この構文で導入される型構成子は、型変数を使うことのできない場所でも使うことができます。例えば、多相関数内の局所モジュールで例外を定義するのに使えます。

let f (type t) () =
  let module M = struct exception E of t end in
  (fun x -> M.E x), (function M.E x -> Some x | _ -> None)
    

別の例を挙げます。

let sort_uniq (type s) (cmp : s -> s -> int) =
  let module S = Set.Make(struct type t = s let compare = cmp end) in
  fun l ->
    S.elements (List.fold_right S.add l S.empty)
    

この構文は、導入した型変数を多相的にしませんが、必要であれば、多相型アノテーションと組合せて使うこともできます。これは第一級のモジュールを使うときに非常に便利です。