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で新しめの機能を二つ組み合わせて使うと大抵バグっちゃうので、妙な使いかたするなって事ですね。