OCaml入門(4)

このページは最後に更新されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

last mod. 2008-04-07 (月) 18:46:53
last mod. 2008-04-07 (月) 18:46:53

多相バリアント(polymorphic variant)

バリアントは定義してからでなければ使えませんが、定義しなくても使うことのできる バリアントがあります。これを 多相バリアント(polymorphic variant) と呼びます。多相バリアントは、"`" を使って表記します。

# [`Int; `Float];;

- : [> `Float | `Int] list = [`Int; `Float]

型に注目して下さい。この list の型は、[> `Float | `Int] list ですが、これは、少なくとも `Float と `Int を持つ list であることを表しています。この `Int や `Float は、どんな名前でも構いません。`A でも `Foo でも、多相バリアントとして正しいです。

# let t = [`A; `B];;

val t : [> `A | `B] list = [`A; `B]
# `C :: t;;

- : [> `A | `B | `C] list = [`C; `A; `B]
# `A :: t;;

- : [> `A | `B] list = [`A; `A; `B]

この場合も、型に注目して下さい。`C :: t の型は、t が拡張されたものになっていることに注意しましょう。

多相バリアントのコンストラクタは、値を取っても構いません。

# [`Int 10; `Float 1.0];;

- : [> `Float of float | `Int of int] list = [`Int 10; `Float 1.]

 

多相バリアントを引数にとる関数を書く事も出来ます。

# let f = function
    `Int x -> (float_of_int x)
  | `Float x -> x
  ;;

val f : [< `Float of float | `Int of int] -> float = 

ここでも型に注目しましょう。f の引数の型は、[< `Float of float | `Int of int] ですが、これは高々 `Float of float か `Int of int しか取れないことを表しています。[> ...] であればそのスーパーセットであってもよく、[< ...] であればそのサブセットでなければならない、と覚えて下さい。

新規 編集 添付