2012/4/12 Alain Frisch
<alain@frisch.fr>
On 04/12/2012 04:16 PM, Philippe Veber wrote:
Isn't this a good use case for polymorphic variants too ?
I don't see how to use polymorphic variants here. The message bus itself need to provide functions like:
val dispatch: message -> unit
val register_listener: (message -> unit) -> unit
How do you define the message type without having access to all possible message constructors?
I reckon you can't, but I mistakenly thought you could at least define the bus without writing the full message type:
module Bus : sig
type 'a t
val create : unit -> 'a t
val dispatch : 'a t -> 'a -> unit
val register : 'a t -> ('a -> unit) -> unit
end
=
struct
type 'a t = ('a -> unit) list ref
let create () = ref []
let dispatch bus msg =
List.iter (fun f -> f msg) !bus
let register bus f =
bus := f :: !bus
end
let bus = Bus.create ()
let () = Bus.register bus (function `a -> print_char 'a')
let () = Bus.register bus (function `b n -> print_int n)
However this is not a legal program:
let () = Bus.register bus (function `b n -> print_int n);;
^^^^
Error: This pattern matches values of type [< `b of 'a ]
but a pattern was expected which matches values of type [< `a ]
These two variant types have no intersection
Well, I mentionned polymorphic variants because you can at least define listeners without knowing the full message type and even reuse them for buses with different message types. So you have a certain flexibility, compared to monomorphic types.
But ok, maybe the remark wasn't even worth 2 cents :o).
Cheers,
ph.