What is it, naokirin?

私の貧弱なOCaml力を晒す 第二回 「module(´ω):つ sig」

今回は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

は型エラーとなります。うーんなかなかややこしい。とりあえず、型を持つようなモジュールのシグネチャの取得時には注意かな。