Hi,
Maybe I misunderstood something, polymorphic variants seem to be able to
describe what you want. By defining the follows (not tested)
type movie = [`Movie of string * int * bool]
type actor = [`Actor of string * int]
type result = [movie | actor]
then easily you get
val array_to_movie: string array -> movie
val array_to_actor: string array -> actor
val process_query: (string array -> 'a) -> 'a -> string array array -> 'a array
val process_movie: string array array -> movie array
val process_actor: string array array -> actor array
Just in case you're afraid that the 'a in process_query is not restrictive
enough, you can restrict it with annotation:
val process_query:
(string array -> ([< result] as 'a)) -> 'a -> string array array -> 'a array
HTH.
"cultural_sublimation" <
cultural_sublimation@...> writes:
> 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