* [Caml-list] Passing printf format strings to functions @ 2004-09-14 21:55 Erik de Castro Lopo 2004-09-14 22:08 ` Micha 2004-09-15 8:12 ` Jean-Christophe Filliatre 0 siblings, 2 replies; 5+ messages in thread From: Erik de Castro Lopo @ 2004-09-14 21:55 UTC (permalink / raw) To: caml-list Hi all, 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 ;; let fmt = Printf.sprintf " %%%ds == %%s\n" 20 ;; print_endline fmt ;; let pairs = [ ("a", "b") ; ("c", "d") ; ("e", "f") ] ;; print_string_pairs fmt pairs ;; and it gives me an error (line 5 is the Printf.printf line): File "fmt.ml", line 5, characters 18-21: This expression has type string but is here used with type ('a -> 'b -> 'c, out_channel, unit) format = ('a -> 'b -> 'c, out_channel, unit, unit) format4 If I replace "fmt" on that line with Printf.printf "%s %s\n" (fst a) (snd a) ; there is no problem. I think this is something to do with type inferencing of format strings but I can't get to the bottom of it. Any suggestions? TIA, Erik -- +-----------------------------------------------------------+ Erik de Castro Lopo nospam@mega-nerd.com (Yes it's valid) +-----------------------------------------------------------+ "Using Java as a general purpose application development language is like going big game hunting armed with Nerf weapons." -- Author Unknown ------------------- 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 ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [Caml-list] Passing printf format strings to functions 2004-09-14 21:55 [Caml-list] Passing printf format strings to functions Erik de Castro Lopo @ 2004-09-14 22:08 ` Micha 2004-09-17 21:32 ` Pierre Weis 2004-09-15 8:12 ` Jean-Christophe Filliatre 1 sibling, 1 reply; 5+ messages in thread From: Micha @ 2004-09-14 22:08 UTC (permalink / raw) To: caml-list; +Cc: Erik de Castro Lopo Hi, Am Tuesday 14 September 2004 23:55 schrieb Erik de Castro Lopo: > Hi all, > let rec print_string_pairs (fmt:string) = > function > [] -> print_endline "" > > | a :: b -> > > Printf.printf fmt (fst a) (snd a) ; > print_string_pairs fmt b > ;; I think the fmt variable has not to be of type string but of some format type. there exists a conversion function in Pervasives: val format_of_string : ('a, 'b, 'c, 'd) format4 -> ('a, 'b, 'c, 'd) format4 (*format_of_string s returns a format string read from the string literal s.*) Michael ------------------- 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 ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [Caml-list] Passing printf format strings to functions 2004-09-14 22:08 ` Micha @ 2004-09-17 21:32 ` Pierre Weis 0 siblings, 0 replies; 5+ messages in thread From: Pierre Weis @ 2004-09-17 21:32 UTC (permalink / raw) To: Micha; +Cc: caml-list, Erik de Castro Lopo > Hi, > > Am Tuesday 14 September 2004 23:55 schrieb Erik de Castro Lopo: > > Hi all, > > let rec print_string_pairs (fmt:string) = > > function > > [] -> print_endline "" > > > > | a :: b -> > > > > Printf.printf fmt (fst a) (snd a) ; > > print_string_pairs fmt b > > ;; > > > I think the fmt variable has not to be of type string but of some > format type. Exactly. Hence you just have to remove the wrong type constraint (fmt:string) and simply write fmt, to get it working beautifully: val print_string_pairs : ('a -> 'b -> 'c, out_channel, unit) format -> ('a * 'b) list -> unit > there exists a conversion function in Pervasives: > val format_of_string : ('a, 'b, 'c, 'd) format4 -> ('a, 'b, 'c, 'd) format4 > (*format_of_string s returns a format string read from the string literal > s.*) In this case I doubt you ever need to use this function: the type-checker will do the job automatically for you! For instance: # print_string_pairs "(%s, %s)";; - : (string * string) list -> unit = <fun> Or even: # print_string_pairs "(%i, %i)";; - : (int * int) list -> unit = <fun> At this point, you should consider renaming your function, given its highly polymorphic nature, it shoould be promoted to print_pairs ... Best regards, -- Pierre Weis INRIA, Projet Cristal, http://pauillac.inria.fr/~weis ------------------- 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 ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [Caml-list] Passing printf format strings to functions 2004-09-14 21:55 [Caml-list] Passing printf format strings to functions Erik de Castro Lopo 2004-09-14 22:08 ` Micha @ 2004-09-15 8:12 ` Jean-Christophe Filliatre 2004-09-15 8:35 ` Erik de Castro Lopo 1 sibling, 1 reply; 5+ messages in thread From: Jean-Christophe Filliatre @ 2004-09-15 8:12 UTC (permalink / raw) To: Erik de Castro Lopo; +Cc: caml-list 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 ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: [Caml-list] Passing printf format strings to functions 2004-09-15 8:12 ` Jean-Christophe Filliatre @ 2004-09-15 8:35 ` Erik de Castro Lopo 0 siblings, 0 replies; 5+ messages in thread From: Erik de Castro Lopo @ 2004-09-15 8:35 UTC (permalink / raw) To: caml-list On Wed, 15 Sep 2004 10:12:28 +0200 Jean-Christophe Filliatre <Jean-Christophe.Filliatre@lri.fr> wrote: Thanks Jean-Christophe for a very thorough and well explained response. > Indeed, there is no static way to check that the resulting format is > indeed of type (string->string->'a,'b,'c) format. Ahh, now I understand. With the knowledge you provided and some hacking I did after I sent the original email, I was able to use a constant format string like: Printf.printf " %-*s %s\n" format_width (fst a) (snd a) ;; and acheive the result I desired. Cheers, Erik -- +-----------------------------------------------------------+ Erik de Castro Lopo nospam@mega-nerd.com (Yes it's valid) +-----------------------------------------------------------+ "The earth is degenerating these days. Bribery and corruption abound. Children no longer mind parents ...and it is evident that the end of the world is approaching fast." -- Assyrian Tablet Engraved in 2800 B.C. ------------------- 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 ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2004-09-17 21:32 UTC | newest] Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2004-09-14 21:55 [Caml-list] Passing printf format strings to functions Erik de Castro Lopo 2004-09-14 22:08 ` Micha 2004-09-17 21:32 ` Pierre Weis 2004-09-15 8:12 ` Jean-Christophe Filliatre 2004-09-15 8:35 ` Erik de Castro Lopo
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox