Version française
Home     About     Download     Resources     Contact us    
Browse thread
Re: [Caml-list] getting the type of a polymorphic data ?
[ Home ] [ Index: by date | by threads ]
[ Search: ]

[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: -- (:)
From: Jean-Baptiste Rouquier <jrouquiethearchiveshouldhaveafewantispamtricks@e...>
Subject: Re: [Caml-list] getting the type of a polymorphic data ?
> Is it reasonable to admit that if Obj.is_int is true for x and y then
Hashtbl.hash is injective ?
No.

# type foo = A | B;;
# let _ = Obj.is_int (Obj.repr 0);;
- : bool = true
# let _ = Obj.is_int (Obj.repr A);;
- : bool = true
# let _ = Hashtbl.hash A;;
- : int = 0
# let _ = Hashtbl.hash 0;;
- : int = 0

The purpose of Hashtbl.hash is exactly no to be injective ! And hashing lists
can't be injective.

        Objective Caml version 3.07+2
# let _ = Hashtbl.hash [0;1];;
- : int = 65599
# let _ = Hashtbl.hash [65599;0];;
- : int = 65599

What you are looking for is a function that associates a unique int to a
variable of any type. This is Oo.id.
As you said, hash is neither injective on int, nor does it allow to distinguish
between types isomorphs to (a subset of) int.

But let's try to first state the requirement :
- the user define it's own types, foo and bar. We can ask him to provide some
functions to handle these types.
- you want a way to print the result x (of type foo or bar) of a computation
with a user provided help message. This help message doesn't depend on the value
of x.
- you want to manipulate the types foo and bar either as int or floats (not both
for the same type), for efficiency.

My approach is to first transform the user defined type into your own good
representation, using user provided functions, then work on int and float for
the branch and bound, without type tricks, and work on more sophisticated types
for printing.
The user has to say whether his type is isomorph to int (and provide the
conversions functions) or to float (ditto). It's safer than trying to guess it
with the Obj module.
You could provide defaults for those conversions functions, based on Obj / hash
tricks, with lots of warnings.

type 'a range =
  | Single of 'a
  | Interval of 'a * 'a

type domain =
  | Discrete of int range list
  | Continuous of float range list (* is Single meaningful ? *)

Your function
[0 .. 1[ U ]2 .. 3[ U ]4 .. 5[ -> [0]
can now be written
val simplify : domain -> domain



Now printing the results. The property lists is a general solution which is good
for your problem. You can also have a specialized (trivial) mechanism, see
below. The core idea is that you must have two different types :
 - one for doing the computations. For efficiency it's int or float.
 - one for printing the results. This one holds the value (possibly converted
back to user defined type) and the help / description string.

# type 'a result = 'a * string;;
# let new_result (a:'a) description = ((a,description) : 'a result);;
val new_result : 'a -> string -> 'a result = <fun>
# let print_int ((a,d): int result) = Printf.printf "%s is %d\n%!" d a;;
val print_int : int result -> unit = <fun>
# let print_float = ...
# let x = new_result 10 "the number of elements in the knapsack";;
val x : int result = ...
# print_int x;;
the number of elements in the knapsack is 10
- : unit = ()

Jean-Baptiste.

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