コマンドラインオプション
G'Caml関係の警告は-w G, -w gで出したり出さなかったりできる様子。
拡張構文
generic
基本。
# let ( + ) = generic ( + ) | ( +.);; Characters 4-33: let ( + ) = generic ( + ) | ( +.);; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Warning G: Unused_var.expression: not yet implemented val ( + ) : [| int -> int -> int | float -> float -> float |] = <generic> # 1 + 2;; - : int = 3 # 1.1 + 2.2;; - : float = 3.3000000000000003
それぞれの型を明記できたりする。再帰させるときに型推論の補助として必要らしい。
# let ( + ) = generic : int -> int -> int => ( + ) | : string -> string -> string => ( ^ );; Characters 4-89: ....( + ) = generic : int -> int -> int => ( + ) | : string -> string -> string => ( ^ ).. Warning G: Unused_var.expression: not yet implemented val ( + ) : [| int -> int -> int | string -> string -> string |] = <generic> # 1 + 2;; - : int = 3 # "a" + "b";; - : string = "ab"
通常は暗黙に生成される、型情報を受け取る部分を、明示的に書くこともできる様子。
# generic val x : {'a} => 'a -> int = fun ty x -> 1;; Unused_var.structure_item val x : { 'a } => 'a -> int = <generic>
[: t :]
型式からRtype.type_exprを得る拡張構文。
( = )で比較したりパターンマッチに使ったりできる。
# [: int :];; - : Rtype.type_expr = [: int(*1*) :] # [: int :];; - : Rtype.type_expr = [: int(*1*) :] # [: int * int :];; - : Rtype.type_expr = [: int(*1*) * int(*1*) :]
r^を使って他の変数を参照できる。
# let x = [: int :] in [: ^x :];; - : Rtype.type_expr = [: int(*1*) :]
typedecl t
型名からRtype.type_declarationを得る拡張構文。typedeclは予約語。
宣言の情報なので識別子になっている型じゃないとダメ。int listやstring * string等は書けない。typedecl listは書ける。
# typedecl int;; - : Rtype.type_declaration = {Rtype.type_name = "int"; Rtype.type_params = []; Rtype.type_arity = 0; Rtype.type_kind = Rtype.Type_abstract; Rtype.type_manifest = None; Rtype.type_variance = []; Rtype.type_defined_with = []} # typedecl in_channel;; - : Rtype.type_declaration = {Rtype.type_name = "in_channel"; Rtype.type_params = []; Rtype.type_arity = 0; Rtype.type_kind = Rtype.Type_abstract; Rtype.type_manifest = None; Rtype.type_variance = []; Rtype.type_defined_with = []}
G'Camlの標準ライブラリ
Builtintypes
Rtypeと別だけどRtypeの中ではObj.magicして使われてたりして、内部の都合で存在するモジュールっぽい。型も<abstr>なので直接使う必要は無さげ。
module Builtintypes :
sig
type type_declaration
val int : type_declaration
val char : type_declaration
val string : type_declaration
val float : type_declaration
val bool : type_declaration
val unit : type_declaration
val exn : type_declaration
val array : type_declaration
val list : type_declaration
val format6 : type_declaration
val option : type_declaration
val nativeint : type_declaration
val int32 : type_declaration
val int64 : type_declaration
val lazy_t : type_declaration
end
Rtype
typedecl t
や[: t :]
で得られる型情報の型が宣言されている。
module Rtype :
sig
module Ident : sig type t = string * int end
module Path :
sig
type t =
Pident of Ident.t
| Pdot of t * string * int
| Papply of t * t
val name : t -> string
end
type mutable_flag = Immutable | Mutable
type label = string
type private_flag = Private | Public
type record_representation =
Record_regular
| Record_float
type type_expr = type_declaration_param raw_type_expr
and type_desc = type_declaration_param raw_type_desc
and type_declaration = type_declaration_param raw_type_declaration
and type_declaration_param = Path.t * type_declaration_box
and type_declaration_box =
Box of type_declaration
and type_kind = type_declaration_param raw_type_kind
and 'a raw_type_expr =
desc : 'a raw_type_desc;
}
and 'a raw_type_desc =
Tvar
| Tarrow of label * 'a raw_type_expr * 'a raw_type_expr
| Ttuple of 'a raw_type_expr list
| Tconstr of 'a * 'a raw_type_expr list
and 'a raw_type_declaration =
type_name : string;
type_params : 'a raw_type_expr list;
type_arity : int;
type_kind : 'a raw_type_kind;
type_manifest : 'a raw_type_expr option;
type_variance : (bool * bool * bool) list;
type_defined_with : 'a list;
}
and 'a raw_type_kind =
Type_abstract
| Type_variant of (string * 'a raw_type_expr list) list * private_flag
| Type_record of (string * mutable_flag * 'a raw_type_expr) list *
record_representation * private_flag
val unbox : type_declaration_box -> type_declaration
val dummy : type_declaration
val equal : type_expr -> type_expr -> bool
val raw_equal :
('a -> 'a -> bool) -> 'a raw_type_expr -> 'a raw_type_expr -> bool
val raw_subst :
('a raw_type_expr * 'a raw_type_expr) list ->
'a raw_type_expr -> 'a raw_type_expr
val subst : (type_expr * type_expr) list -> type_expr -> type_expr
val attached_info : 'a raw_type_expr -> 'a list
val iter_type_expr :
('a raw_type_expr -> unit) -> 'a raw_type_expr -> unit
val reset_names : unit -> unit
val print_path : Format.formatter -> Path.t -> unit
val raw_print :
(Format.formatter -> 'a -> unit) ->
Format.formatter -> 'a raw_type_expr -> unit
val raw_print_type_declarations :
(Format.formatter -> 'a -> unit) ->
Format.formatter -> 'a raw_type_declaration list -> unit
val print : Format.formatter -> type_expr -> unit
val print_type_declarations :
Format.formatter -> type_declaration list -> unit
val print_related_type_declarations :
Format.formatter -> type_declaration -> unit
val int : type_declaration
val char : type_declaration
val string : type_declaration
val float : type_declaration
val bool : type_declaration
val unit : type_declaration
val exn : type_declaration
val array : type_declaration
val list : type_declaration
val format6 : type_declaration
val option : type_declaration
val nativeint : type_declaration
val int32 : type_declaration
val int64 : type_declaration
val lazy_t : type_declaration
val builtin_types : type_declaration list
end
gcamllib
Cplus
intとfloatのオーバーロードされた加算。intとfloatを直接足すこともできる。
module Cplus :
sig
val plus :
[| int -> int -> int | float -> float -> float | int -> float -> float
| float -> int -> float | int -> int -> float |]
end
Garith
組み込み型の四則演算を全部( + ), ( - ), ( * ), ( / )で書けるようにする。
module Garith :
sig
val ( + ) :
[| int -> int -> int | float -> float -> float
| int32 -> int32 -> int32 | int64 -> int64 -> int64
| nativeint -> nativeint -> nativeint |]
val ( - ) :
[| int -> int -> int | float -> float -> float
| int32 -> int32 -> int32 | int64 -> int64 -> int64
| nativeint -> nativeint -> nativeint |]
val ( * ) :
[| int -> int -> int | float -> float -> float
| int32 -> int32 -> int32 | int64 -> int64 -> int64
| nativeint -> nativeint -> nativeint |]
val ( / ) :
[| int -> int -> int | float -> float -> float
| int32 -> int32 -> int32 | int64 -> int64 -> int64
| nativeint -> nativeint -> nativeint |]
end
Gcaml
module Gcaml :
sig
val typeof : { 'a } => 'a -> Rtype.type_expr
type dyn
exception Coercion_failure of Rtype.type_expr * Rtype.type_expr
val dyn : { 'a } => 'a -> dyn
val coerce : { 'a } => dyn -> 'a
val type_of_dyn : dyn -> Rtype.type_expr
val obj_of_dyn : dyn -> Obj.t
val dyn_of : Rtype.type_expr -> Obj.t -> dyn
end
typeofは値の型を取得する。多相型の関数の中で引数の型を知りたい時に使える。
dynは型無し変数として使える。coerceで値を取り出す。取り出した値は型が不定のままオーバーロードされた関数に渡すこともできる。具体的な型が指定された時点で型が合わなければCoercion_failureが発生する。
# Gcaml.typeof 1;; - : Rtype.type_expr = [: int(*1*) :] # let x = Gcaml.dyn 2;; val x : Gcaml.dyn = <abstr> # Gcaml.coerce x;; - : { Gcaml.dyn -> 'b < { 'a } => Gcaml.dyn -> 'a } => 'b = <generic> # (Gcaml.coerce x : int);; - : int = 2 # let y = Plus.double (Gcaml.coerce x);; val y : { 'b -> 'b < { 'a -> 'a -> 'a < [| int -> int -> int | float -> float -> float |] } => 'a -> 'a, Gcaml.dyn -> 'b < { 'c } => Gcaml.dyn -> 'c } => 'b = <generic> # (y: int);; - : int = 4 # (y: float);; Exception: Gcaml.Coercion_failure ([: int(*1*) :], [: float(*4*) :]).
Generic
タプルとかリストとか中まで見てくれるiterとmap。
何も説明が無く、使い方はわかるようなわからないような。
module Generic :
sig
val iter :
((Gcaml.dyn -> unit) -> Gcaml.dyn -> unit) -> Gcaml.dyn -> unit
val map :
((Gcaml.dyn -> Gcaml.dyn) -> Gcaml.dyn -> Gcaml.dyn option) ->
Gcaml.dyn -> Gcaml.dyn
end
# Generic.iter (fun x y -> try Gprint.eprint (Gcaml.coerce y: int) with Gcaml.Coercion_failure _ -> ()) (Gcaml.dyn (1, 2));; 1 2 - : unit = () # Generic.iter (fun x y -> try Gprint.eprint (Gcaml.coerce y: int) with Gcaml.Coercion_failure _ -> ()) (Gcaml.dyn [(1, 2); (3, 4)]);; 1 2 3 4 - : unit = ()
Gprint
説明不要。無いと死ぬ。G'Camlの存在意義と言っていいモジュール。
module Gprint :
sig
type depth_info =
max_depth : int;
cur_depth : int;
}
type base_printer = depth_info -> Format.formatter -> Obj.t -> unit
val base_printers :
(Rtype.type_declaration * (base_printer list -> base_printer)) list
type printer =
Rtype.type_expr -> depth_info -> Format.formatter -> Obj.t -> unit
val gen_print : printer -> printer
val printer :
Rtype.type_expr -> ?max_depth:int -> Format.formatter -> Obj.t -> unit
val print : { 'a } => ?max_depth:int -> Format.formatter -> 'a -> unit
val eprint : { 'a } => ?max_depth:int -> 'a -> unit
end
Gtest
このモジュールは何がやりたいのかよくわからない。
module Gtest :
sig
val t_dest_ :
Rtype.type_declaration_param Rtype.raw_type_expr -> Obj.t -> Gcaml.dyn
val t_dest : { 'a } => 'a -> Gcaml.dyn
val t_cnst_ : Rtype.type_expr -> 'a -> Gcaml.dyn
val t_cnst : { 'a } => 'a -> Gcaml.dyn
end
Plus
intとfloatのオーバーロードされた加算。
module Plus :
sig
val plus : [| int -> int -> int | float -> float -> float |]
val double :
{ 'a -> 'a -> 'a < [| int -> int -> int | float -> float -> float |] }
=> 'a -> 'a
end
Rec
intのリストを再帰的に辿って表示してくれる。
module Rec :
sig
val print :
[| int -> unit
| { 'b -> unit < 'a, 'b list -> unit < 'a } => 'b list -> unit |]
as 'a
end
# Rec.print [1; 2; 3];; 123- : unit = () # Rec.print [[1; 2]; [3; 4]];; 1234- : unit = ()
Safevio
型情報も一緒に出力するタイプのマーシャリングらしい。
module Safevio :
sig
type fingerprint =
BuiltinBase of string
| Digest of Digest.t
| Recursive of string
type fingerprint_type_expr = fingerprint Rtype.raw_type_expr
type type_signature = fingerprint Rtype.raw_type_declaration list
val type_expr : Rtype.type_expr -> fingerprint_type_expr
val fingerprint : Rtype.type_declaration -> fingerprint
val type_signature : Rtype.type_declaration -> type_signature
val print_type_signature :
Format.formatter -> Rtype.type_declaration -> unit
val string_of_type_signature : Rtype.type_declaration -> string
val output_value : { 'a } => out_channel -> 'a -> unit
val input_value : { 'a } => in_channel -> 'a
end