"ocaml_beginners"::[] De-unifying variant types
Hi,
Here's the situation: I am building a small module to encapsulate the
nasty type-unsafe task of extracting data stored in a Postgresql database.
(I am using the postgresql-ocaml bindings by Markus Mottl to connect
to Postgresql).
For simplicity sake, let us assume there are only two tables in
the database: "movies" (containing 3 fields: title, year, and B&W,
respectively of types text, integer, and boolean), and "actors"
(containing 2 fields: name and age, of text and integer types).
Now, as far as I can tell, regardless of the Postgresql datatypes, any
row resulting from a SELECT statement will be seen by the Ocaml program
as a "string array". Therefore, I have made two simple functions that
convert the "string array" into proper tuples of movies and actors:
type movie_t = string * int * bool
type actor_t = string * int
type query_result = Movie of movie_t | Actor of actor_t
let array_to_movie a = Movie (a.(0), int_of_string a.(1),
bool_of_string a.(2))
let array_to_actor a = Actor (a.(0), int_of_string a.(2))
The reason why the movie_t and actor_t were unified under that
"query_result" variant is because there is a "process_query" function
which should accept results based both on movies or actors:
let process_query array_converter converter_template result =
let size = Array.length result in
let converted = Array.make size converter_template in
for i = 0 to size-1 do
converted.(i) <- array_converter (result.(i))
done;
converted
Now, all of the these functions are fairly low-level and are not meant
to be used
directly by the users of the module. Instead, the user should handle
all tasks
via two other functions, process_movies and process_actors, as follows:
let process_movies result =
let converter_template = Movie ("", 0, false) in
process_query array_to_movie converter_template result
let process_actors result =
let converter_template = Actor ("", 0) in
process_query array_to_actor converter_template result
This is all fine and dandy, except that because of the unification,
the signature of both process_movies and process_actors is the same:
val process_movies : string array array -> query_result array
val process_actors : string array array -> query_result array
My question is the following: how do I undo the unification of movie_t
and actor_t, so that externally, the signatures of these functions are
different? (listed below). I don't want the caller to be bothering
with matches, and quite frankly, the fact that movie_t and actor_t were
unified is an implementation detail, used only to avoid the duplication
of the process_query code.
val process_movies : string array array -> movie_t array
val process_actors : string array array -> actor_t array
Thanks a lot for your help!!
Cheers,
C.S.