モジュールのmixinってできませんか?

ちょっと考えたけど,できなさそうだなあ…

module M1 = struct
  let foo = ...
end

module M2 = struct
  let bar = ...
end

module M3 = Mixin.Make(M1,M2)

... (M3.foo ...) ...
... (M3.bar ...) ...

とかできたら嬉しいのに.

とりあえず,Mixin.Makeの引数の型がめちゃくちゃになるという点で,既にユーザーレベルでの実装は無理臭い.言語レベルでの実装にしても,リフレクション臭い危険な機能が無いと無理か.


例えばstringの集合が欲しかったとする.

module StringSet = Set.Make(
  struct
    type t = string
    let compare = compare
  end)

とすれば良い.

しかし,

map:StringSet.t -> StringSet.t
from_list: StringSet.elt list -> StringSet.t

みたいな操作も欲しい場合,困ったことになる.

let string_set_from_list = List.fold_left (fun s e -> StringSet.add e s) StringSet.empty
let string_set_map f ss = StringSet.fold (fun e s -> StringSet.add (f e) s) ss StringSet.empty

とすればとりあえず目的を果たすことは可能だが,これてすごく美しく無いと思いませんか?string_set_from_listとかstring_set_mapとかは,StringSetの中にあって欲しいのだ.*1

こういう状況は,mixinを導入することによりスマートに解決できる(んじゃないかと思う).結局,Ocamlで入れるのは難しいだろうけど…

*1:しかも,IntSetみたいのを考えた場合には,また手で定義しなくちゃならないし…