Browse thread
question about polymorphic methods
- Warren Harris
[
Home
]
[ Index:
by date
|
by threads
]
[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
[ Message by date: previous | next ] [ Message in thread: previous | next ] [ Thread: previous | next ]
Date: | 2007-09-24 (02:09) |
From: | Warren Harris <warren@l...> |
Subject: | question about polymorphic methods |
I have a simple output stream class that abstracts over out_channels and buffers. I would like to add a printf method that takes a format directive, and calls the appropriate Printf function. To do this, I needed to introduce a polymorphic method which abstracts over the first type parameter to the format type (the 'a parameter of printf): class type ['b] out_stream = object method print : string -> unit method printf : 'a . ('a, 'b, unit) format -> 'a method flush : unit end class out_stream_of_buffer buf = object (self : Buffer.t #out_stream) method print str = Buffer.add_string buf str method printf : 'a . ('a, Buffer.t, unit) format -> 'a = fun fmt -> Printf.bprintf buf fmt method flush = () end class out_stream_of_channel och = object (self : out_channel #out_stream) method print str = output_string och str method printf : 'a . ('a, out_channel, unit) format -> 'a = fun fmt -> Printf.fprintf och fmt method flush = flush och end However, as you can see from this code, I also needed to abstract over the second parameter to format in the definition of the out_stream class type ('b is the type of the first argument of the Printf function). This type parameter propagates through numerous places in my code, in some cases requiring other methods to become polymorphic. This is unfortunate, since 'b should be completely hidden by the particular implementation of out_stream (Buffer.t in the case of out_stream_of_buffer, or out_channel in the case of out_stream_of_channel). Is there some other way to implement this that I'm overlooking? It seems like 'b should be "monomorphic" ('_b) and determined uniquely whenever the printf method is called. However, if I eliminate the 'b class type parameter, I get the following error: .......... out_stream = object method print : string -> unit method printf : 'a . ('a, 'b, unit) format -> 'a method flush : unit end Some type variables are unbound in this type: class type out_stream = object method flush : unit method print : string -> unit method printf : ('a, 'b, unit) format -> 'a end The method printf has type 'a. ('a, 'b, unit) format -> 'a where 'b is unbound Any suggestions on a better way to do this would be appreciated. BTW, all this code would be unnecessary if ocaml provided an output_channel_of_buffer primitive. :-) Warren