メモ

OCaml 3.12での話なんですが

(* is_empty_ Map.Make(String) something
   is_empty_ Map.Make(Int32) something *)
let is_empty_ modl =
  let module Modl = (val modl : Map.S) in
  let aux (map : 'a Modl.t) = Modl.is_empty map in
    aux (* local module 'Modl' try escape to global! *)

しょうがないからlet module Modl = ...としていて、本質的にはmodlと同じ筈なのに、ところがmodlと書けないからModlと書くとローカルなモジュールが逃亡をはかろうとしていると言われて、
まぁローカルモジュールが逃げようとしていて怒られるのは良いとして、いや・・・そういうことじゃないんです・・・って感じになっていて、
どうすれば良いんでしょう。

出来ると嬉しいかもしれない

let is_empty_ (type x) modl =
  let module Modl = (val modl : Map.S with type ('a t) = x) in
  let aux (map : x) = Modl.is_empty map in
    aux

いや...しかしコレは...

一応
http://caml.inria.fr/pub/docs/manual-ocaml/manual021.html
を見ると

With first-class modules, it is possible to parametrize some code over the implementation of a module without using a functor.

let sort (type s) set l =
  let module Set = (val set : Set.S with type elt = s) in
    Set.elements (List.fold_right Set.add l Set.empty)

The type inferred for this function is (module Set.S with type elt = ’a) -> ’a list -> ’a list.

とすればローカルからのモジュール脱出は防げると書いてるんですよね。

メモメモ

ゴミバージョン

let is_empty_ (type x) modl map =
  let module Modl = (val modl : Map.S) in
  let (map_ : x Modl.t) = Obj.magic map in
    Modl.is_empty map_

このis_empty_の型は

type:   (module Map.S) -> 'a -> bool

となっていてゴミ使えないですよ…。