小ネタ集
いろいろ思いつく訳です。
recursive module
module rec M : sig f : unit -> unit end = M let _ = M.f
こりゃ一体どういうことなんでしょうね。
これに関連して、camlinternalMod.ml の ignore pad1 から ignore pad8 までがとっても気になります。
binary operator with optional arguments
let (+) ?(x=0) y z = x + y + z let _ = 1 + 2 let _ = (+) ~x:3 1 2
何かの役に立ちそうです。ただし、(1 + 2) ~x:3 は出来ません。
private alias がやっぱりイマイチ使えない
module M : sig type 'a t = private 'a val pack : 'a -> 'a t end = struct type 'a t = 'a let pack x = x end let l = [] let packed_l = M.pack l
pack は関数なので、polymorphic な値を pack しても monomorphic になってしまいます。
- pack する対象(l) は M の外に置きたい。
- eta conversion したくない。つうか、上の例だと出来ない。
なので詰んでしまいました。
Obj.magic が関数なのは困る。
上の続き。邪道ですが、pack じゃなくて、Obj.magic を使ってみました。
let packed_l : 'a list M.t = Obj.magic l
これでもダメです。Obj.magic もやっぱ関数なので、無理矢理型は変えられますが、expansiveness は変えられない。
- 関数じゃないプリミティブの Obj.magic
- private を一時的に無視できるような仕組み (オレオレ friend モジュール?)
- private っぽいけど一方通行じゃなくて、明示的 coercion を使えば行き来できるような abbreviate type: (t :> s), (s :> t) が出来るけど t と s は unifiable ではない。
のうちどれかが欲しいなぁ。最後のが格好よさそうだ。