Browse thread
[Caml-list] Passing printf format strings to functions
-
Erik de Castro Lopo
- Micha
- Jean-Christophe Filliatre
[
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: | 2004-09-15 (08:12) |
From: | Jean-Christophe Filliatre <Jean-Christophe.Filliatre@l...> |
Subject: | Re: [Caml-list] Passing printf format strings to functions |
Erik de Castro Lopo writes: > > I've got a little problem which I can't seem to get to the > bottom of. The following code snippet won't compile: > > let rec print_string_pairs (fmt:string) = > function > [] -> print_endline "" > | a :: b -> > Printf.printf fmt (fst a) (snd a) ; > print_string_pairs fmt b > ;; A format is not of type "string" but of type "('a,'b,'c) format". Here is how you can write such a function: ====================================================================== let rec print_string_pairs (fmt:(string->string->'a,'b,'c) format) = ... ====================================================================== But the type of fmt can be inferred, thus you can simply write: ====================================================================== let rec print_string_pairs fmt = ... ====================================================================== Note that this second version is now polymorphic : it applies to any format of type ('a -> 'b -> 'c, out_channel, unit) format and a list of type ('a * 'b) list: ====================================================================== # print_string_pairs "%s->%s\n" [ ("a", "b") ; ("c", "d") ; ("e", "f") ];; a->b c->d e->f # print_string_pairs "%d->%d\n" [ 1,2; 3,4; 5,6 ];; 1->2 3->4 5->6 ====================================================================== > let fmt = Printf.sprintf " %%%ds == %%s\n" 20 ;; > > print_endline fmt ;; > > let pairs = [ ("a", "b") ; ("c", "d") ; ("e", "f") ] ;; > > print_string_pairs fmt pairs ;; There is a additional difficuly here, because you want to build a format string dynamically. With the code above, fmt will be of type string, and then cannot be passed to print_string_pairs. As suggested by Michael, you can use format_of_string to convert a string into a format: ====================================================================== # let fmt = format_of_string "%20s == %s\n";; val fmt : (string -> string -> '_a, '_b, '_c, '_a) format4 = <abstr> # print_string_pairs fmt [ ("a", "b") ; ("c", "d") ; ("e", "f") ];; a == b c == d e == f ====================================================================== But format_of_string only applies to a _constant_ string, not to a string built from an evaluation: ====================================================================== # let fmt = format_of_string (Printf.sprintf " %%%ds == %%s\n" 20) ;; Characters 27-71: let fmt = format_of_string (Printf.sprintf " %%%ds == %%s\n" 20) ;; ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ This expression has type string but is here used with type ('a, 'b, 'c, 'd) format4 ====================================================================== Indeed, there is no static way to check that the resulting format is indeed of type (string->string->'a,'b,'c) format. Hope this helps, -- Jean-Christophe ------------------- To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/ Beginner's list: http://groups.yahoo.com/group/ocaml_beginners