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