* [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