今回はmodule type ofによるモジュールのシグネチャの取得。
・・・あれ、また3.12の新機能じゃないか!
それはいいんです、それは。最近ちょうど使う機会があったんですっ!たまたま使っただけですっ!
module type of
シグネチャを書くときに、モジュール同士を組み合わせる際やライブラリのモジュールのシグネチャを取得したいときに使えます。これがあるとシグネチャが結構きれいにかけます。
例えば既にあるライブラリを少し拡張したいときなどに有効です。
module MyList : sig include module type of List val rfind: ('a -> bool) -> 'a list -> 'a end = struct include List let rfind f l = find f (rev l) end
今回はListにrfindという後方から検索をかけるものを実装してみました。実際にMyListのシグネチャがどうなっているかというと、
module MyList : sig val length : 'a list -> int val hd : 'a list -> 'a ... val rfind : ('a -> bool) -> 'a list -> 'a end
のようになります。
ちゃんとListのシグネチャが取得できています。便利!綺麗!やったね!
ただ注意点もあるらしく、(詳しくはこちら -> モジュールを「拡張」する― 3.12.0 の機能を使って…(みるけどうまくいかない) - http://d.hatena.ne.jp/camlspotter/20101207/1291726392)
module MySys : sig include module type of Sys end = struct include Sys end
のようにしたとき、
let _ = MySys.Signal_default = Sys.Signal_default
は型エラーとなります。うーんなかなかややこしい。とりあえず、型を持つようなモジュールのシグネチャの取得時には注意かな。