Source

planck / lib / stream_intf.ml

(** Stream interface *)

(** Minimum specification to create a stream *)
module type Base = sig

  module Elem : Elem.S
  (** Type of the stream element *)

  module Pos : Position.S
  (** Position of the stream. 
      Position is a part of the stream attribute defined below. *)

  module Attr : sig
    type t
    val position : t -> Pos.t
  end 
  (** Stream attribute, available for each stream element and the null.
      The position of the stream must be obtained from [Attr.t].
  *)

end

(* Standard interface *)
module type X = sig

  (** the parameters *)    
  type elem
  type pos
  type attr
  type desc

  type t = desc Lazy.t
  (** Stream type [t] is lazy by nature, and [desc] is its forced form. *)

  val null : attr -> t
  (** Create a null stream *)

  val null_desc : attr -> desc
  val cons_desc : elem -> attr -> t -> desc
  (** Create a null/cons cell desc, useful for stream creation *)

  (** Destructors *)
  val peek : t -> (elem * t) option

  val is_null : t -> bool
  (** Null check *)

  val attr : t -> attr
  val position : t -> pos
  (** Attribute and Position of the head element or null *)

  val to_list : t -> elem list
  val iter : (elem -> unit) -> t -> unit
  val fold_right : (elem -> 'a -> 'a) -> t -> 'a -> 'a
  val map : (elem -> 'a) -> t -> 'a Spotlib.Spot.Stream.t
  (** Iteration, folding and map *)

  val rev_between : t -> t -> elem list
  (** [rev_between t1 t2] returns the elemens between the two steam positions [t1] and [t2].
      [t2] must be a postfix of [t1].
      The elements are returned in the reverse order in the stream.

      NOTE:
      The behaviour of [rev_between t1 t2] when [t2] is not a postfix of [t1] is not defined.
      No sanity check at all.

      NOTE:
      This can be quite costy operation. Use with care.
  *)

  val between : t -> t -> elem list
  (** Same as [rev_between] but the elements are in the same ordered in the streams.

      [between t1 t2] is actually defined as [List.rev (rev_between t1 t2)].
      The same notes of [rev_between] apply to this function too.
  *)
end

module type S = sig
  include Base
  include X with type elem := Elem.t
            and  type pos  := Pos.t
            and  type attr := Attr.t
end