Browse thread
Installing pretty-printers automagically
- Markus Mottl
[
Home
]
[ Index:
by date
|
by threads
]
[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
| Date: | -- (:) |
| From: | Markus Mottl <markus.mottl@g...> |
| Subject: | Installing pretty-printers automagically |
Hi,
though the idea is not new, more precisely, I have shamelessly stolen
it from Gerd Stolpmann's findlib sources, it still seems not widespread
and is such a useful thing to have that it should be mentioned here on
the list.
You will quite often want to have custom pretty-printers for your
datatypes in the toplevel. Preferably, they should be installed as
soon as the library implementing them has been loaded.
The solution for this is quite simple, and I have just implemented it
in the LACAML-library so that matrices and vectors can be printed in
the toplevel.
Assuming you have already implemented a pretty-printer with the correct
signature in module "My_module":
val pp_my_type : Format.formatter -> my_type -> unit
Then just create another module in your library:
---------------------------------------------------------------------------
let printers =
[
"My_module.pp_my_type";
]
let eval_string
?(print_outcome = false) ?(err_formatter = Format.err_formatter) str =
let lexbuf = Lexing.from_string str in
let phrase = !Toploop.parse_toplevel_phrase lexbuf in
Toploop.execute_phrase print_outcome err_formatter phrase
let rec install_printers = function
| [] -> true
| printer :: printers ->
let cmd = Printf.sprintf "#install_printer %s;;" printer in
eval_string cmd && install_printers printers
let () =
if not (install_printers printers) then
Format.eprintf "Problem installing printers@."
---------------------------------------------------------------------------
Just add further pretty-printers to the list "printers" if required.
If you link this module into a byte-code library and load it into the
toplevel (using #load), you will be able to print your types using the
custom pretty-printers.
There is one caveat here: the resulting library cannot be used for linking
with byte-code executables, because the toplevel is not available there.
Therefore, if you want to implement a library, you will have to link
two separate ones: one with and one without the module for installing
the printers.
If you happen to use "ocamlfind" to "#require" your libraries, you just
need to add a line to the META-file for each kind of library. The right
one will be chosen automatically then, e.g.:
archive(byte)="mylib.cma"
archive(byte,toploop)="mylib_top.cma"
Here is a short demonstration using the pretty-printers of the
LACAML-library in the toplevel while computing the singular value
decomposition of a 3x3 Hilbert-matrix:
---------------------------------------------------------------------------
# #require "lacaml";;
/usr/local/home/godi/godi/lib/ocaml/std-lib/bigarray.cma: loaded
/usr/local/home/godi/godi/lib/ocaml/site-lib/lacaml: added to search path
/usr/local/home/godi/godi/lib/ocaml/site-lib/lacaml/lacaml_top.cma: loaded
# open Lacaml.D;;
# let mat = Mat.hilbert 3;;
val mat : Lacaml_float64.mat =
1 0.5 0.333333
0.5 0.333333 0.25
0.333333 0.25 0.2
# gesvd mat;;
- : Lacaml_float64.vec * Lacaml_float64.mat * Lacaml_float64.mat =
( 1.40832
0.122327
0.00268734,
-0.827045 0.547448 0.127659
-0.459864 -0.52829 -0.713747
-0.323298 -0.649007 0.688672,
-0.827045 -0.459864 -0.323298
0.547448 -0.52829 -0.649007
0.127659 -0.713747 0.688672)
---------------------------------------------------------------------------
Enjoy this trick...
Best regards,
Markus
--
Markus Mottl http://www.ocaml.info markus.mottl@gmail.com