monadic combinators for lists and klists

This commit is contained in:
Simon Cruanes 2014-06-24 16:23:30 +02:00
parent 9da54f3e5a
commit e5a842829e
4 changed files with 93 additions and 4 deletions

View file

@ -237,6 +237,33 @@ let to_gen l =
l := l';
Some x
(** {2 Monadic Operations} *)
module type MONAD = sig
type 'a t
val return : 'a -> 'a t
val (>>=) : 'a t -> ('a -> 'b t) -> 'b t
end
module Traverse(M : MONAD) = struct
open M
let map_m f l =
let rec aux acc l = match l () with
| `Nil -> return (of_list (List.rev acc))
| `Cons (x,l') ->
f x >>= fun x' ->
aux (x' :: acc) l'
in
aux [] l
let sequence_m l = map_m (fun x->x) l
let rec fold_m f acc l = match l() with
| `Nil -> return acc
| `Cons (x,l') ->
f acc x >>= fun acc' -> fold_m f acc' l'
end
(** {2 IO} *)
let pp ?(sep=",") pp_item buf l =

View file

@ -106,6 +106,21 @@ val exists2 : ('a -> 'b -> bool) -> 'a t -> 'b t -> bool
val merge : 'a ord -> 'a t -> 'a t -> 'a t
(** Merge two sorted iterators into a sorted iterator *)
(** {2 Monadic Operations} *)
module type MONAD = sig
type 'a t
val return : 'a -> 'a t
val (>>=) : 'a t -> ('a -> 'b t) -> 'b t
end
module Traverse(M : MONAD) : sig
val sequence_m : 'a M.t t -> 'a t M.t
val fold_m : ('b -> 'a -> 'b M.t) -> 'b -> 'a t -> 'b M.t
val map_m : ('a -> 'b M.t) -> 'a t -> 'b t M.t
end
(** {2 Conversions} *)
val of_list : 'a list -> 'a t

View file

@ -495,6 +495,34 @@ module Zipper = struct
| _, [] -> raise Not_found
end
(** {2 Monadic Operations} *)
module type MONAD = sig
type 'a t
val return : 'a -> 'a t
val (>>=) : 'a t -> ('a -> 'b t) -> 'b t
end
module Traverse(M : MONAD) = struct
open M
let map_m f l =
let rec aux f acc l = match l with
| [] -> return (List.rev acc)
| x::tail ->
f x >>= fun x' ->
aux f (x' :: acc) tail
in aux f [] l
let sequence_m l = map_m (fun x->x) l
let rec fold_m f acc l = match l with
| [] -> return acc
| x :: l' ->
f acc x
>>= fun acc' ->
fold_m f acc' l'
end
(** {2 Conversions} *)
type 'a sequence = ('a -> unit) -> unit
@ -527,6 +555,8 @@ let random_choose l = match l with
let i = Random.State.int st len in
List.nth l i
let random_sequence l st = map (fun g -> g st) l
let to_seq l k = List.iter k l
let of_seq seq =
let l = ref [] in

View file

@ -220,6 +220,21 @@ module Zipper : sig
@raise Not_found if the zipper is at an end *)
end
(** {2 Monadic Operations} *)
module type MONAD = sig
type 'a t
val return : 'a -> 'a t
val (>>=) : 'a t -> ('a -> 'b t) -> 'b t
end
module Traverse(M : MONAD) : sig
val sequence_m : 'a M.t t -> 'a t M.t
val fold_m : ('b -> 'a -> 'b M.t) -> 'b -> 'a t -> 'b M.t
val map_m : ('a -> 'b M.t) -> 'a t -> 'b t M.t
end
(** {2 Conversions} *)
type 'a sequence = ('a -> unit) -> unit
@ -229,14 +244,16 @@ type 'a printer = Buffer.t -> 'a -> unit
type 'a formatter = Format.formatter -> 'a -> unit
type 'a random_gen = Random.State.t -> 'a
val random : 'a random_gen -> 'a list random_gen
val random_non_empty : 'a random_gen -> 'a list random_gen
val random_len : int -> 'a random_gen -> 'a list random_gen
val random : 'a random_gen -> 'a t random_gen
val random_non_empty : 'a random_gen -> 'a t random_gen
val random_len : int -> 'a random_gen -> 'a t random_gen
val random_choose : 'a list -> 'a random_gen
val random_choose : 'a t -> 'a random_gen
(** Randomly choose an element in the list.
@raise Not_found if the list is empty *)
val random_sequence : 'a random_gen t -> 'a t random_gen
val to_seq : 'a t -> 'a sequence
val of_seq : 'a sequence -> 'a t