From: Jean-Christophe Filliatre <Jean-Christophe.Filliatre@lri.fr>
To: Erik de Castro Lopo <ocaml-erikd@mega-nerd.com>
Cc: caml-list@inria.fr
Subject: Re: [Caml-list] Passing printf format strings to functions
Date: Wed, 15 Sep 2004 10:12:28 +0200 [thread overview]
Message-ID: <16711.63852.127954.905979@gargle.gargle.HOWL> (raw)
In-Reply-To: <20040915075547.54c0bef6.ocaml-erikd@mega-nerd.com>
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
next prev parent reply other threads:[~2004-09-15 8:12 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2004-09-14 21:55 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 [this message]
2004-09-15 8:35 ` Erik de Castro Lopo
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=16711.63852.127954.905979@gargle.gargle.HOWL \
--to=jean-christophe.filliatre@lri.fr \
--cc=caml-list@inria.fr \
--cc=ocaml-erikd@mega-nerd.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox