Version française
Home     About     Download     Resources     Contact us    
Browse thread
Format.sprintf and "%a"
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Pierre Weis <weis@p...>
Subject: Re: Format.sprintf and "%a"
> Hello,
> 
> I'm teaching myself Ocaml and have run up against a problem I can't
> solve in connection with the format module.  For many of the types
> in my code, I have defined pretty-printing functions with type
> (Format.formatter -> <type> -> unit), e.g.,
> 
>   type foo = Foo | Bar
>   let fmt_foo f x =
>     match x with
>       Foo -> Format.fprintf f "Foo"
>     | Bar -> Format.fprintf f "Bar"
>   in
>   Format.printf "Test: %a@." fmt_foo Foo
> 
> Works great, but when I try it with sprintf, I get the following:
> 
>   let s = Format.sprintf "Test: %a@." fmt_foo Foo
>   This expression has type
>     ((Format.formatter -> foo -> unit) -> foo -> unit,
>      Format.formatter, unit)
>     format
>   but is here used with type
>     ((Format.formatter -> foo -> unit) -> foo -> unit,
>      unit, string)
>     format
> 
> [Note: I retyped these examples by hand, I hope they're accurate.]
> 
> I can see the correlation of the signatures in the error message to
> those of fprintf and sprintf in Format.mli, but the type magic that
> seems to be occuring in the implementation of the Format modules
> is beyond me.  Can someone explain what is going on here?

Nothing more than the reported type error: your functions  are
designed to return unit (they work by side effect) not string (which
would mean they are functional), and this is obviously uncompatible.

>  Is there a way to use my formatting functions with sprintf?

Yes. Use the special Format.str_formatter predefined formatter. It
works as usual side effecting formatters (hence it is compatible wih
your fmt_* functions), except that it records the output into a string
buffer. Hence, you would have to flush str_formatter explicitely, to
get the corresponding string result. For instance:

let s =
 Format.fprintf str_formatter "Test: %a@." fmt_foo Foo;
 Format.flush_str_formatter ();;
val s : string = "Test: Foo\n"

Pierre Weis

INRIA, Projet Cristal, Pierre.Weis@inria.fr, http://cristal.inria.fr/~weis/