package monadlib

  1. Overview
  2. Docs

Here, we create a stream monad from a definite collection monad Monad.BaseCollectionM. The inner monad will be used to represent the generations in the stream. The order of elements in each generation should not matter, so you might want to use a set or a bag. If you want to live life on the edge, just remember that your code should not depend on the order of elements within generations (you can, of course, depend on the order that generations appear in the stream). You can enforce this constraint by performing, say, a sort on each generation.

Parameters

module M : sig ... end

Signature

include StreamC with type 'a t = 'a M.m LazyList.node_t and type 'a m = 'a M.m LazyList.t
include Stream with type 'a t = 'a M.m LazyList.node_t with type 'a m = 'a M.m LazyList.t
type 'a t = 'a M.m LazyList.node_t
include LazyPlus with type 'a m = 'a t Stdlib.Lazy.t with type 'a m = 'a M.m LazyList.t
include BaseLazyPlus with type 'a m = 'a t Stdlib.Lazy.t with type 'a m = 'a M.m LazyList.t
include BatInterfaces.Monad with type 'a m = 'a t Stdlib.Lazy.t with type 'a m = 'a M.m LazyList.t
type 'a m = 'a M.m LazyList.t

The type of a monad producing values of type 'a.

include MonadPlus with type 'a m := 'a m
include BasePlus with type 'a m := 'a m
include BatInterfaces.Monad with type 'a m := 'a m
val plus : 'a m -> 'a m -> 'a m
include Monad with type 'a m := 'a m
include BatInterfaces.Monad with type 'a m := 'a m
include Applicative.Applicative with type 'a m := 'a m
include Applicative.Base with type 'a m := 'a m
val (<*>) : ('a -> 'b) m -> 'a m -> 'b m
val lift1 : ('a -> 'b) -> 'a m -> 'b m
val lift2 : ('a -> 'b -> 'c) -> 'a m -> 'b m -> 'c m
val lift3 : ('a -> 'b -> 'c -> 'd) -> 'a m -> 'b m -> 'c m -> 'd m
val lift4 : ('a -> 'b -> 'c -> 'd -> 'e) -> 'a m -> 'b m -> 'c m -> 'd m -> 'e m
val (<$>) : ('a -> 'b) -> 'a m -> 'b m

Alias for lift1.

val sequence : 'a m list -> 'a list m
val map_a : ('a -> 'b m) -> 'a list -> 'b list m
val (<*) : 'a m -> 'b m -> 'a m
val (>*) : 'a m -> 'b m -> 'b m
val (>>=) : 'a m -> ('a -> 'b m) -> 'b m
val join : 'a m m -> 'a m
val filter_m : ('a -> bool m) -> 'a list -> 'a list m
val onlyif : bool -> unit m -> unit m
val unless : bool -> unit m -> unit m
val ignore : 'a m -> unit m
val filter : ('a -> bool) -> 'a m -> 'a m
val of_list : 'a list -> 'a m
val sum : 'a list m -> 'a m
val msum : 'a m list -> 'a m
val guard : bool -> 'a m -> 'a m
val transpose : 'a list m -> 'a m list

Generalises matrix transposition. This will loop infinitely if BasePlus.null cannot answer true for zeroes.

val of_llist : 'a LazyList.t -> 'a m
val lsum : 'a LazyList.t m -> 'a m
val lmsum : 'a m LazyList.t -> 'a m
val ltranspose : 'a LazyList.t m -> 'a m LazyList.t

Generalises matrix transposition. You don't necessarily have to worry about correctly implementing BaseLazyPlus.null for this function, since the return value can happily be infinite.

val iterate : ('a m -> 'a m) -> 'a m -> 'a m

The sum of the stream [f x, f (f x), f (f (f x)),...]

val delay : 'a m -> 'a m

Delay a stream by one time step. This is needed when you write recursive streams and you have to avoid deadlock. The nice thing about Ocaml here is that it will generally detect deadlock for you, announcing to you that you're writing viciously circular lists!

val to_depth : int -> 'a m -> 'a m

Terminate discovery at some depth.

include BaseCollectionM with type 'a m := 'a m

difference p xs ys removes all elements from xs which are less than or equal to some element in ys, according to the partial order p.

include BaseLazyPlus with type 'a m := 'a m
include BatInterfaces.Monad with type 'a m := 'a m
val bind : 'a m -> ('a -> 'b m) -> 'b m

Monadic binding.

bind m f executes first m then f, using the result of m.

val return : 'a -> 'a m

Return a value, that is, put a value in the monad.

val zero : unit -> 'a m
val lplus : 'a m -> 'a m Stdlib.Lazy.t -> 'a m
val null : 'a m -> bool

null x implies that x is zero. If you do not want to or cannot answer whether a given x is zero, then null x should be false.

val difference : ('a -> 'a -> bool) -> 'a m -> 'a m -> 'a m

difference p xs ys removes all elements from xs which are less than or equal to some element in ys, according to the partial order p.

val unique : ?cmp:('a -> 'a -> bool) -> 'a m -> 'a m

unique eq xs removes duplicates according to the function cmp.

val maxima : ('a -> 'a -> bool) -> 'a m -> 'a m

maxima p xs leaves only the maximal elements according to the partial order p.

val nub : ('a -> 'a -> bool) -> 'a m -> 'a m

nub p xs ys is the same as maxima, but some values might be treated as greater than others depending on their position in the collection.

For instance, with lists, we treat elements that occur earlier in the list as always greater than elements that occur later, otherwise we use p. This is really just an optimisation: in order to retrieve any value from maxima p xs, the maxima function will have had to seen every value. Not so with nub.

OCaml

Innovation. Community. Security.