It seems that sprintf
does not allow %a
in its format specifier. Is this right? If so, why is it like this, and is there a workaround?
Example. I have a long and complicated datatype:
type t = Foo | Baz
I have a pretty-printer for this type, that sends a string representation of its values to an arbitrary out_channel
:
let pp_t oc = function
| Foo -> fprintf oc "Foo"
| Baz -> fprintf oc "Baz"
If I then write
let _ = printf "%a=%d" pp_t Foo 2
or
let _ = eprintf "%a=%d" pp_t Foo 2
then everything works fine -- the message "Foo=2" ends up on my stdout or my stderr as expected. But if I write
let s = sprintf "%a=%d" pp_t Foo 2
then I get a compilation error, complaining that the argument pp_t
has type out_channel -> t -> unit
but an expression was expected of type unit -> 'a -> string
.
Is it simply not possible to use %a
inside a format specifier for sprintf
?
In order to get away with specific datatypes showing up in your formatting functions you should always use the Format
module and devise pretty printers for your types that have the signature val pp_t : Format.formatter -> t -> unit
; this is also the signature the toplevel asks for to install custom printers with #install_printer
for your datatypes.
Equipped with such a function you can then simply use Format.asprintf
with "%a"
.