osiire’s blog

ふしぎなそふとやさん

列多相な型を宣言

id:mzpが書かないようなので、私が書く。
OCamlでは、「int型のidというメソッドとstring型のunameというメソッドを持つ何か型」という書き方が出来る。例えば、

        Objective Caml version 3.11.0+beta1

# open Format;;
# let show (lst : 'a t list) =
      List.iter (fun o -> fprintf std_formatter "id=%d, name=%s" o#id o#uname) lst;;
val show : < id : int; uname : string; .. > list -> unit = <fun>

型表示されているオブジェクトの「..」の部分が列多相というやつ。普段こーゆー使い方していると、わざわざ< id : int; uname : string; .. >の型を手書きする事はあまりないのだけけれど、< id : int; uname : string; .. >をperson型として宣言したいとする。ところが、素直に書くと

# type person = < id : int; uname : string; .. >;;
Error: Unbound type parameter ..
# 

Unboundだと怒られる。列多相もパラメトリック多相のひとつだと思えば、まぁ納得。で、こーゆー場合どうするかというと、

# class type person = object val id : int val uname : string end;;
class type person = object val id : int val uname : string end
# type 'a t = 'a constraint 'a = #person;;
type 'a t = 'a constraint 'a = #person
# let show (lst : 'a t list) =
      List.iter (fun o -> fprintf std_formatter "id=%d, name=%s" o#id o#uname) lst;;  
val show : < id : int; uname : string; .. > t list -> unit = <fun>

「#」というキーワードを型の前につけると、開いた型を表現できるらしい。これは多相バリアントでも同じみたい。

# type t = [`A];;
type t = [ `A ]
#type 'a z = 'a constraint 'a = #t;;
Warning D: this syntax is deprecated.
type 'a z = 'a constraint 'a = [< t ]

お?なんか文法が非難されている?あれー?