module P: sig .. end
Producers
type 'a t = {
}
val empty : unit -> 'a t
Empty producer, get will always return None.
val map : ('a -> 'b) -> 'a t -> 'b t
map f prod returns a  producer that produces f x when
    prod produces x
val when_none : unit Join.chan -> 'a t -> 'a t
when_none k prod returns a  producer that acts like prod.
    Additionnaly, k is sent a message whenever prod outputs None
val of_list : 'a list -> 'a t
of_list xs returns a producer for the elements of xs
val to_list : ('a t * 'a list Join.chan) Join.chan
to_list (prod,k) asynchronously consumes all the elements produced
    by prod. The complete list, in production order, is sent on k
val of_text : in_channel -> string t
of_text chan returns a producer prod built from the lines of
    channel chan. Notice that chan is closed when end of file
    or I/O error occurs.
    Killing prod also closes chan.
val to_text : (string t * out_channel * unit Join.chan) Join.chan
to_text (prod,chan,k)  asynchronously consumes all the elements produced
    by prod, writing lines to channel chan in production order.
    A unit message is sent on k when production is over,
    i.e. when prod emits None.
    Notice that prod is killed and chan closed in case of I/O error.
val to_text_close : (string t * out_channel) Join.chan
Same as 
JoinCom.P.to_text above except that the channel is closed
    as sooon as the producer emits 
None.