diff options
| author | Arnaud Spiwack | 2014-10-17 17:58:11 +0200 |
|---|---|---|
| committer | Arnaud Spiwack | 2014-10-22 07:31:45 +0200 |
| commit | 8532caf90a0bca7ddf94d24f552b5faa98b0f66a (patch) | |
| tree | 453bb575fbe5421bce3ca1453a233edac0fd478b /lib | |
| parent | 000c1e636b033c57fc070d323140f9e26296b9c0 (diff) | |
Add a two-list monadic fold_left iterator.
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/monad.ml | 29 | ||||
| -rw-r--r-- | lib/monad.mli | 15 |
2 files changed, 44 insertions, 0 deletions
diff --git a/lib/monad.ml b/lib/monad.ml index b165ffbfb3..dc5809407b 100644 --- a/lib/monad.ml +++ b/lib/monad.ml @@ -52,6 +52,21 @@ module type ListS = sig operator calls its second argument in a tail position. *) val fold_left : ('a -> 'b -> 'a t) -> 'a -> 'b list -> 'a t + + (** {6 Two-list iterators} *) + + (** Raised when an combinator expects several lists of the same size + but finds that they are not. Exceptions must be raised inside + the monad, so two-list combinators take an extra argument to + raise the exception. *) + exception SizeMismatch + + (** [fold_left2 r f s l1 l2] behaves like {!fold_left} but acts + simultaneously on two lists. Returns [r SizeMismatch] if both lists + do not have the same length. *) + val fold_left2 : (exn->'a t) -> + ('a -> 'b -> 'c -> 'a t) -> 'a -> 'b list -> 'c list -> 'a t + end module type S = sig @@ -113,6 +128,20 @@ module Make (M:Def) : S with type +'a t = 'a M.t = struct f x a >>= fun x' -> f x' b >>= fun x'' -> fold_left f x'' l + + + exception SizeMismatch + + let rec fold_left2 r f x l1 l2 = + match l1,l2 with + | [] , [] -> return x + | [a] , [b] -> f x a b + | a1::a2::l1 , b1::b2::l2 -> + f x a1 b1 >>= fun x' -> + f x' a2 b2 >>= fun x'' -> + fold_left2 r f x'' l1 l2 + | _ , _ -> r SizeMismatch + end end diff --git a/lib/monad.mli b/lib/monad.mli index 768fb739d3..c72e584db1 100644 --- a/lib/monad.mli +++ b/lib/monad.mli @@ -54,6 +54,21 @@ module type ListS = sig operator calls its second argument in a tail position. *) val fold_left : ('a -> 'b -> 'a t) -> 'a -> 'b list -> 'a t + + (** {6 Two-list iterators} *) + + (** Raised when an combinator expects several lists of the same size + but finds that they are not. Exceptions must be raised inside + the monad, so two-list combinators take an extra argument to + raise the exception. *) + exception SizeMismatch + + (** [fold_left2 r f s l1 l2] behaves like {!fold_left} but acts + simultaneously on two lists. Returns [r SizeMismatch] if both lists + do not have the same length. *) + val fold_left2 : (exn->'a t) -> + ('a -> 'b -> 'c -> 'a t) -> 'a -> 'b list -> 'c list -> 'a t + end module type S = sig |
