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 FAA08159; Thu, 28 Jun 2001 05:00:32 +0200 (MET DST) X-Authentication-Warning: pauillac.inria.fr: majordomo set sender to owner-caml-list@pauillac.inria.fr using -f Received: from concorde.inria.fr (concorde.inria.fr [192.93.2.39]) by pauillac.inria.fr (8.7.6/8.7.3) with ESMTP id FAA08231 for ; Thu, 28 Jun 2001 05:00:31 +0200 (MET DST) Received: from smtp4-cm.mail.eni.net (smtp4-cm.mail.eni.net [216.133.226.137]) by concorde.inria.fr (8.11.1/8.10.0) with ESMTP id f5S30TH02916 for ; Thu, 28 Jun 2001 05:00:29 +0200 (MET DST) Received: from CHECKERATH ([216.233.204.162]) by smtp4-cm.mail.eni.net (8.9.3/8.9.3) with SMTP id UAA18698 for ; Wed, 27 Jun 2001 20:00:27 -0700 Date: Wed, 27 Jun 2001 20:00:27 -0700 Message-Id: <200106280300.UAA18698@smtp4-cm.mail.eni.net> From: Chris Hecker To: caml-list@inria.fr Subject: [Caml-list] there has to be a better way to write this code Sender: owner-caml-list@pauillac.inria.fr Precedence: bulk I'm trying to write a little property system, which means I have a dictionary/hash with strings for keys and a variant of different types for the data. Then, I define get_float and get_string and the like on this hash, and the functions either return the type if it exists, or throw an exception if it doesn't. The attached code below works fine. My problem is that the attached code is really pretty verbose and redundant. Each of the get_* functions has a lot of duplicate code in it, and I think there must be a better way. I'd like to write something like this (not really caml syntax, but you get the idea): let get_float h s = get_meta h s (Float el -> el) but I can't see any way to get that to work. The closest I can come is this: let get_meta h s f = try List.iter f (Hashtbl.find_all h s); raise Not_found with Match_failure _ -> raise Not_found exception Found_float of float let get_float h s = try get_meta h s (function Float el -> raise (Found_float el)) with Found_float el -> el which isn't much of a savings over the code below, and probably isn't worth it. (Have I mentioned how annoying that exception at global scope is? :) If I didn't want to have multiple types per key, I could do this: let get_float h s = match Hashtbl.find h s with Float el -> el | _ -> raise Not_found which is slightly better, but having the multiple types is nice (especially since Hashtbl supports it). Thoughts? Chris ---------------------------------------- type data_type = String of string | Float of float | Vec of (float * float) | Bool of bool let h = Hashtbl.create 7 let _ = Hashtbl.add h "foo" (String "foo_string"); Hashtbl.add h "foof" (Float 3.141); Hashtbl.add h "bar" (String "bar_string"); Hashtbl.add h "bar" (Float 2.718); Hashtbl.add h "vec" (Vec (1.0,2.0)); Hashtbl.add h "yes" (Bool true); Hashtbl.add h "no" (Bool false) exception Found_float of float exception Found_string of string exception Found_vec of (float * float) exception Found_bool of bool let get_float h s = try List.iter (function Float el -> raise (Found_float el) | _ -> ()) (Hashtbl.find_all h s); raise Not_found with Found_float el -> el let get_string h s = try List.iter (function String el -> raise (Found_string el) | _ -> ()) (Hashtbl.find_all h s); raise Not_found with Found_string el -> el let get_vec h s = try List.iter (function Vec el -> raise (Found_vec el) | _ -> ()) (Hashtbl.find_all h s); raise Not_found with Found_vec el -> el let get_bool h s = try List.iter (function Bool el -> raise (Found_bool el) | _ -> ()) (Hashtbl.find_all h s); raise Not_found with Found_bool el -> el ------------------- Bug reports: http://caml.inria.fr/bin/caml-bugs FAQ: http://caml.inria.fr/FAQ/ To unsubscribe, mail caml-list-request@inria.fr Archives: http://caml.inria.fr