Recursive module
ノードが Set で実装された tree を書こうと思ったら、recursive module が必要だった。まあ、明示的に signature を書かなければいけないことを除けば recursive module は別に難しくない。書いてみてから OCaml リファレンスを見たら例としてほとんど同じコードが載っていた。とほほ。
type は type としか相互再帰できなかったが、recursive module を使えば、この制限がなくなり、functor とか class とかとも相互再帰定義できる、はずだが:
module rec M : sig type t = Foo of N.c end = struct type t = Foo of N.c end and N : sig class c : object method x : M.t end end = struct class c = object (self) method x = M.Foo (self :> c) end end
と書いたら謎のエラーになった:
Error: Signature mismatch: Modules do not match: sig class c : object method x : M.t end end is not included in sig class c : object method x : M.t end end Type declarations do not match: type c = N.c is not included in type c = < x : M.t >
一字一句同じなんですが、なんでマッチしませんか?
定義の :> c を :> N.c にしたら通る(自己再帰もできる。当然か):
module rec M : sig type t = Foo of N.c end = struct type t = Foo of N.c end and N : sig class c : object method x : M.t end end = struct class c = object (self) method x = M.Foo (self :> N.c) end end
これはさすがにバグじゃないかな。3.11+dev12 Private_abbrevs+natdynlink (2008-02-29) にて確認。レポートすることにする。
まあ、OCamlで新しめの機能を二つ組み合わせて使うと大抵バグっちゃうので、妙な使いかたするなって事ですね。