#install_printer

晴 - Note

多分、普通のプリンタの作り方だとこんな感じです。

let print_sring ppf str = Format.fprintf ppf "utf8_of_string \"%s\"" str;;
#install_printer print_string;;

型が、Format.formatter -> 'a -> unitになるような関数を作って、#install_printerしてあげると、'a型の値のプリンタになる。のだと思っていたら、'a -> unitでもOKだったのですね…しかも上手く動かないと。LXはアホか。

PrintfモジュールがFormatモジュールのラッパーになっているようなイメージです。Formatモジュールのfprintとかpp_print_stringとかは、Format.formatter型の引数を受け付けるようになっているのですが(ppf = pretty printing formatterという仮引数がそれです)、その引数に破壊的に操作するようになっているみたいです。

Printfモジュールは、Formatモジュールの関数にデフォルトのformatterを部分適用したような感じで定義されているイメージです。ですのでFormatモジュールの関数と混ぜると、どのppfをどの順序で操作しているのかよくわからなくなって、出力順がおかしくなることがあるのだと理解しています。


ちなみにFormatモジュールの真価は、%a@,だと思ってます。%aで自分の作ったプリンタ(=Format.formatter -> 'a -> unit型の関数)を繋げていって、@,で整形、というのは、割と便利だと思います。%aが型付きなのもポイントです。

上のと同じ動作をするプリンタを無理やり%aを使って書くと、こんな感じになります。

let print_sring ppf str = Format.fprintf ppf "utf8_of_string \"%a\""
                            Format.pp_print_string str;;
#install_printer print_string;;
let f a = ();;
#install_printer f;;

とかすると、ちょっと愉快ですね。