Reviewed By: ngorogiannis Differential Revision: D20482771 fbshipit-source-id: aa523e90amaster
							parent
							
								
									24a26c8a23
								
							
						
					
					
						commit
						04df3ca460
					
				@ -0,0 +1,117 @@
 | 
				
			||||
(*
 | 
				
			||||
 * Copyright (c) Facebook, Inc. and its affiliates.
 | 
				
			||||
 *
 | 
				
			||||
 * This source code is licensed under the MIT license found in the
 | 
				
			||||
 * LICENSE file in the root directory of this source tree.
 | 
				
			||||
 *)
 | 
				
			||||
 | 
				
			||||
open (
 | 
				
			||||
  Base :
 | 
				
			||||
    (module type of Base with module Format := Base.Format [@warning "-3"]) )
 | 
				
			||||
 | 
				
			||||
(* undeprecate *)
 | 
				
			||||
external ( == ) : 'a -> 'a -> bool = "%eq"
 | 
				
			||||
 | 
				
			||||
exception Not_found = Caml.Not_found
 | 
				
			||||
 | 
				
			||||
include Base.List
 | 
				
			||||
 | 
				
			||||
let rec pp ?pre ?suf sep pp_elt fs = function
 | 
				
			||||
  | [] -> ()
 | 
				
			||||
  | x :: xs ->
 | 
				
			||||
      Option.iter pre ~f:(Format.fprintf fs) ;
 | 
				
			||||
      pp_elt fs x ;
 | 
				
			||||
      ( match xs with
 | 
				
			||||
      | [] -> ()
 | 
				
			||||
      | xs -> Format.fprintf fs "%( %)%a" sep (pp sep pp_elt) xs ) ;
 | 
				
			||||
      Option.iter suf ~f:(Format.fprintf fs)
 | 
				
			||||
 | 
				
			||||
let pop_exn = function x :: xs -> (x, xs) | [] -> raise Not_found
 | 
				
			||||
 | 
				
			||||
let find_map_remove xs ~f =
 | 
				
			||||
  let rec find_map_remove_ ys = function
 | 
				
			||||
    | [] -> None
 | 
				
			||||
    | x :: xs -> (
 | 
				
			||||
      match f x with
 | 
				
			||||
      | Some x' -> Some (x', rev_append ys xs)
 | 
				
			||||
      | None -> find_map_remove_ (x :: ys) xs )
 | 
				
			||||
  in
 | 
				
			||||
  find_map_remove_ [] xs
 | 
				
			||||
 | 
				
			||||
let fold_option xs ~init ~f =
 | 
				
			||||
  With_return.with_return
 | 
				
			||||
  @@ fun {return} ->
 | 
				
			||||
  Some
 | 
				
			||||
    (fold xs ~init ~f:(fun acc elt ->
 | 
				
			||||
         match f acc elt with Some res -> res | None -> return None ))
 | 
				
			||||
 | 
				
			||||
let map_preserving_phys_equal map t ~f =
 | 
				
			||||
  let change = ref false in
 | 
				
			||||
  let t' =
 | 
				
			||||
    map t ~f:(fun x ->
 | 
				
			||||
        let x' = f x in
 | 
				
			||||
        if not (x' == x) then change := true ;
 | 
				
			||||
        x' )
 | 
				
			||||
  in
 | 
				
			||||
  if !change then t' else t
 | 
				
			||||
 | 
				
			||||
let filter_map_preserving_phys_equal filter_map t ~f =
 | 
				
			||||
  let change = ref false in
 | 
				
			||||
  let t' =
 | 
				
			||||
    filter_map t ~f:(fun x ->
 | 
				
			||||
        let x'_opt = f x in
 | 
				
			||||
        ( match x'_opt with
 | 
				
			||||
        | Some x' when x' == x -> ()
 | 
				
			||||
        | _ -> change := true ) ;
 | 
				
			||||
        x'_opt )
 | 
				
			||||
  in
 | 
				
			||||
  if !change then t' else t
 | 
				
			||||
 | 
				
			||||
let filter_map_preserving_phys_equal t ~f =
 | 
				
			||||
  filter_map_preserving_phys_equal filter_map t ~f
 | 
				
			||||
 | 
				
			||||
let map_preserving_phys_equal t ~f = map_preserving_phys_equal map t ~f
 | 
				
			||||
 | 
				
			||||
let rev_map_unzip xs ~f =
 | 
				
			||||
  fold xs ~init:([], []) ~f:(fun (ys, zs) x ->
 | 
				
			||||
      let y, z = f x in
 | 
				
			||||
      (y :: ys, z :: zs) )
 | 
				
			||||
 | 
				
			||||
let remove_exn ?(equal = phys_equal) xs x =
 | 
				
			||||
  let rec remove_ ys = function
 | 
				
			||||
    | [] -> raise Not_found
 | 
				
			||||
    | z :: xs ->
 | 
				
			||||
        if equal x z then rev_append ys xs else remove_ (z :: ys) xs
 | 
				
			||||
  in
 | 
				
			||||
  remove_ [] xs
 | 
				
			||||
 | 
				
			||||
let remove ?equal xs x =
 | 
				
			||||
  try Some (remove_exn ?equal xs x) with Not_found -> None
 | 
				
			||||
 | 
				
			||||
let rec rev_init n ~f =
 | 
				
			||||
  if n = 0 then []
 | 
				
			||||
  else
 | 
				
			||||
    let n = n - 1 in
 | 
				
			||||
    let xs = rev_init n ~f in
 | 
				
			||||
    f n :: xs
 | 
				
			||||
 | 
				
			||||
let symmetric_diff ~compare xs ys =
 | 
				
			||||
  let rec symmetric_diff_ xxs yys =
 | 
				
			||||
    match (xxs, yys) with
 | 
				
			||||
    | x :: xs, y :: ys ->
 | 
				
			||||
        let ord = compare x y in
 | 
				
			||||
        if ord = 0 then symmetric_diff_ xs ys
 | 
				
			||||
        else if ord < 0 then Either.First x :: symmetric_diff_ xs yys
 | 
				
			||||
        else Either.Second y :: symmetric_diff_ xxs ys
 | 
				
			||||
    | xs, [] -> map ~f:Either.first xs
 | 
				
			||||
    | [], ys -> map ~f:Either.second ys
 | 
				
			||||
  in
 | 
				
			||||
  symmetric_diff_ (sort ~compare xs) (sort ~compare ys)
 | 
				
			||||
 | 
				
			||||
let pp_diff ~compare sep pp_elt fs (xs, ys) =
 | 
				
			||||
  let pp_diff_elt fs elt =
 | 
				
			||||
    match (elt : _ Either.t) with
 | 
				
			||||
    | First x -> Format.fprintf fs "-- %a" pp_elt x
 | 
				
			||||
    | Second y -> Format.fprintf fs "++ %a" pp_elt y
 | 
				
			||||
  in
 | 
				
			||||
  pp sep pp_diff_elt fs (symmetric_diff ~compare xs ys)
 | 
				
			||||
@ -0,0 +1,57 @@
 | 
				
			||||
(*
 | 
				
			||||
 * Copyright (c) Facebook, Inc. and its affiliates.
 | 
				
			||||
 *
 | 
				
			||||
 * This source code is licensed under the MIT license found in the
 | 
				
			||||
 * LICENSE file in the root directory of this source tree.
 | 
				
			||||
 *)
 | 
				
			||||
 | 
				
			||||
open Base
 | 
				
			||||
include module type of Base.List
 | 
				
			||||
open Import0
 | 
				
			||||
 | 
				
			||||
val pp :
 | 
				
			||||
     ?pre:(unit, unit) fmt
 | 
				
			||||
  -> ?suf:(unit, unit) fmt
 | 
				
			||||
  -> (unit, unit) fmt
 | 
				
			||||
  -> 'a pp
 | 
				
			||||
  -> 'a list pp
 | 
				
			||||
(** Pretty-print a list. *)
 | 
				
			||||
 | 
				
			||||
val pp_diff :
 | 
				
			||||
     compare:('a -> 'a -> int)
 | 
				
			||||
  -> (unit, unit) fmt
 | 
				
			||||
  -> 'a pp
 | 
				
			||||
  -> ('a list * 'a list) pp
 | 
				
			||||
 | 
				
			||||
val pop_exn : 'a list -> 'a * 'a list
 | 
				
			||||
 | 
				
			||||
val find_map_remove :
 | 
				
			||||
  'a list -> f:('a -> 'b option) -> ('b * 'a list) option
 | 
				
			||||
 | 
				
			||||
val fold_option :
 | 
				
			||||
  'a t -> init:'accum -> f:('accum -> 'a -> 'accum option) -> 'accum option
 | 
				
			||||
(** [fold_option t ~init ~f] is a short-circuiting version of [fold] that
 | 
				
			||||
    runs in the [Option] monad. If [f] returns [None], that value is
 | 
				
			||||
    returned without any additional invocations of [f]. *)
 | 
				
			||||
 | 
				
			||||
val map_preserving_phys_equal : 'a t -> f:('a -> 'a) -> 'a t
 | 
				
			||||
(** Like map, but preserves [phys_equal] if [f] preserves [phys_equal] of
 | 
				
			||||
    every element. *)
 | 
				
			||||
 | 
				
			||||
val filter_map_preserving_phys_equal : 'a t -> f:('a -> 'a option) -> 'a t
 | 
				
			||||
(** Like filter_map, but preserves [phys_equal] if [f] preserves
 | 
				
			||||
    [phys_equal] of every element. *)
 | 
				
			||||
 | 
				
			||||
val rev_map_unzip : 'a t -> f:('a -> 'b * 'c) -> 'b list * 'c list
 | 
				
			||||
(** [rev_map_unzip ~f xs] is [unzip (rev_map ~f xs)] but more efficient. *)
 | 
				
			||||
 | 
				
			||||
val remove_exn : ?equal:('a -> 'a -> bool) -> 'a list -> 'a -> 'a list
 | 
				
			||||
(** Returns the input list without the first element [equal] to the
 | 
				
			||||
    argument, or raise [Not_found] if no such element exists. [equal]
 | 
				
			||||
    defaults to physical equality. *)
 | 
				
			||||
 | 
				
			||||
val remove : ?equal:('a -> 'a -> bool) -> 'a list -> 'a -> 'a list option
 | 
				
			||||
val rev_init : int -> f:(int -> 'a) -> 'a list
 | 
				
			||||
 | 
				
			||||
val symmetric_diff :
 | 
				
			||||
  compare:('a -> 'a -> int) -> 'a t -> 'a t -> ('a, 'a) Either.t t
 | 
				
			||||
					Loading…
					
					
				
		Reference in new issue