ボクがObj.magicを使うシチュエーション
要約
- とりあえずコンパイルを通したいときは、Obj.magicを使うと便利だよ
- でも、Obj.magicを使ったコードを公開したり、レポジトリにコミットしたらダメだよ
Obj.magicがないと困るとき
シグネチャ付きのモジュールを書くとき、先にシグネチャを書いたりしますよね。
module M : sig val f : int -> int val g : char -> char end = struct end
で、fから順に実装していきます。
module M : sig val f : int -> int val g : char -> char end = struct let f n = n + 1 end
で、この段階でfに型エラーがないか確かめるために、コンパイルしたくてもできません。
$ ocamlc foo.ml File "foo.ml", line 4, characters 6-33: Error: Signature mismatch: Modules do not match: sig val f : int -> int end is not included in sig val f : int -> int val g : char -> char end The field `g' is required but not provided
そこで...
Obj.magicの出番です。
まず、Obj.magicを使って'a型の変数を作ります。
(* val undef : 'a = <poly> *) let undef = Obj.magic 42
で、これを使って、gを実装します。
let undef = Obj.magic 42 module M : sig val f : int -> int val g : char -> char end = struct let f n = n + 1 (* gに適当な実装を与える *) let g = undef end
これで、コンパイルできるようになります。やったね。
$ ocamlc foo.ml $
注意
でも、undefが入ったままのコードを公開したり、レポジトリにコミットしたらダメだよ。