From mboxrd@z Thu Jan 1 00:00:00 1970 Received: (from majordomo@localhost) by pauillac.inria.fr (8.7.6/8.7.3) id KAA15954; Wed, 15 Sep 2004 10:12:41 +0200 (MET DST) X-Authentication-Warning: pauillac.inria.fr: majordomo set sender to owner-caml-list@pauillac.inria.fr using -f Received: from nez-perce.inria.fr (nez-perce.inria.fr [192.93.2.78]) by pauillac.inria.fr (8.7.6/8.7.3) with ESMTP id KAA15383 for ; Wed, 15 Sep 2004 10:12:38 +0200 (MET DST) Received: from lri.lri.fr (lri.lri.fr [129.175.15.1]) by nez-perce.inria.fr (8.13.0/8.13.0) with ESMTP id i8F8CScP018066 (version=TLSv1/SSLv3 cipher=EDH-RSA-DES-CBC3-SHA bits=168 verify=NO) for ; Wed, 15 Sep 2004 10:12:28 +0200 Received: from localhost (localhost [127.0.0.1]) by lri.lri.fr (Postfix) with ESMTP id 7B60419E7D8; Wed, 15 Sep 2004 10:12:28 +0200 (CEST) Received: from lri.lri.fr ([127.0.0.1]) by localhost (lri.lri.fr [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 19124-01; Wed, 15 Sep 2004 10:12:28 +0200 (CEST) Received: from pc8-123 (pc8-123 [129.175.8.123]) by lri.lri.fr (Postfix) with ESMTP id 5B9A419E7D3; Wed, 15 Sep 2004 10:12:28 +0200 (CEST) Received: from filliatr by pc8-123 with local (Exim 3.35 #1 (Debian)) id 1C7Utw-0004lY-00; Wed, 15 Sep 2004 10:12:28 +0200 From: Jean-Christophe Filliatre MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Message-ID: <16711.63852.127954.905979@gargle.gargle.HOWL> Date: Wed, 15 Sep 2004 10:12:28 +0200 To: Erik de Castro Lopo Cc: caml-list@inria.fr Subject: Re: [Caml-list] Passing printf format strings to functions In-Reply-To: <20040915075547.54c0bef6.ocaml-erikd@mega-nerd.com> References: <20040915075547.54c0bef6.ocaml-erikd@mega-nerd.com> X-Mailer: VM 7.03 under Emacs 20.7.2 Reply-To: Jean-Christophe.Filliatre@lri.fr (Jean-Christophe Filliatre) X-Virus-Scanned: by amavisd-new at lri.fr X-Loop: caml-list@inria.fr X-Spam: no; 0.00; filliatre:01 filliatre:01 lri:01 caml-list:01 passing:01 printf:01 fmt:01 endline:01 printf:01 fmt:01 string-:01 string-:01 inferred:01 sprintf:01 endline:01 Sender: owner-caml-list@pauillac.inria.fr Precedence: bulk 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 = # 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