diff options
Diffstat (limited to 'lib/util.ml')
-rw-r--r-- | lib/util.ml | 31 |
1 files changed, 28 insertions, 3 deletions
diff --git a/lib/util.ml b/lib/util.ml index 953c8187e..33f91b04e 100644 --- a/lib/util.ml +++ b/lib/util.ml @@ -250,6 +250,13 @@ let list_for_all_i p = let list_except x l = List.filter (fun y -> not (x = y)) l +let list_remove = list_except (* Alias *) + +let rec list_remove_first a = function + | b::l when a = b -> l + | b::l -> b::list_remove_first a l + | [] -> raise Not_found + let list_for_all2eq f l1 l2 = try List.for_all2 f l1 l2 with Failure _ -> false let list_map_i f = @@ -361,12 +368,12 @@ let list_share_tails l1 l2 = let list_join_map f l = List.flatten (List.map f l) -let rec list_fold_map f e = function +let rec list_fold_map f e = function | [] -> (e,[]) - | h::t -> + | h::t -> let e',h' = f e h in let e'',t' = list_fold_map f e' t in - e'',h'::t' + e'',h'::t' (* (* tail-recursive version of the above function *) let list_fold_map f e l = @@ -378,6 +385,10 @@ let list_fold_map f e l = (e',List.rev lrev) *) +(* The same, based on fold_right, with the effect accumulated on the right *) +let list_fold_map' f l e = + List.fold_right (fun x (l,e) -> let (y,e) = f x e in (y::l,e)) l ([],e) + let list_map_assoc f = List.map (fun (x,a) -> (x,f a)) (* Arrays *) @@ -595,6 +606,20 @@ let array_map_left_pair f a g b = r, s end +let pure_functional = false + +let array_fold_map' f v e = +if pure_functional then + let (l,e) = + Array.fold_right + (fun x (l,e) -> let (y,e) = f x e in (y::l,e)) + v ([],e) in + (Array.of_list l,e) +else + let e' = ref e in + let v' = Array.map (fun x -> let (y,e) = f x !e' in e' := e; y) v in + (v',!e') + (* Matrices *) let matrix_transpose mat = |