多相なprintを求めて-その1-

30分プログラムその201。いい加減ネタを探すのが大変なので、ちょっと大きめな課題を一日30分づつ進める方針にチャレンジ。
で、デバッグに便利な多相なprintをOCamlで実装してみよう。
要するに、Haskellで言うとshow、型で言うと'a -> stringのような関数が欲しい。

Toploop

http://alohakun.blog7.fc2.com/blog-entry-584.html

> 文字列を eval したり,型情報を取得したりするやりかた
Toplevelというモジュールが標準でインストールされています。秘密のAPIなのでドキュメントはtoplevel.mliのコメントしかありませんが。

らしいので、toplevel/*.mliを探してみる。

toploop.mliの

val print_out_value : formatter -> Outcometree.out_value -> unit) ref

あたりが怪しいのだけれども、Outcometree.out_valueを'aから作る方法がなさそうなので断念。

ところで、Toploopモジュールを使っていても、ocamlcでコンパイルできるこの不思議。トップレベル専用じゃないの?

Printexc

Toploopは諦めて、比較的近い機能を持っているPrintexcモジュールを見てみる。
このモジュールは任意の例外を文字列にできる。

val to_string : exn -> string
let to_string = function
  ...
  | x ->
      let x = Obj.repr x in
      let constructor = (Obj.magic(Obj.field (Obj.field x 0) 0) : string) in
      constructor ^ (fields x)

Obj.magicが怪しいな、という辺りで時間切れ。続きはまた明日。