Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source
Page
Library
Module
Module type
Parameter
Class
Class type
Source
fQueue.ml1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124type 'a digit = Zero | One of 'a | Two of 'a * 'a | Three of 'a * 'a * 'a type 'a t = | Shallow of 'a digit | Deep of {s: int; f: 'a digit; m: ('a * 'a) t Lazy.t; r: 'a digit} let empty = Shallow Zero exception Empty let _one x = Shallow (One x) let _two x y = Shallow (Two (x, y)) let _deep s f m r = assert (f <> Zero && r <> Zero) ; Deep {s; f; m; r} let is_empty = function | Shallow Zero -> true | Shallow (One _ | Two _ | Three _) | Deep _ -> false let _empty = Lazy.from_val empty let rec push : 'a. 'a t -> 'a -> 'a t = fun q x -> match q with | Shallow Zero -> _one x | Shallow (One y) -> Shallow (Two (y, x)) | Shallow (Two (y, z)) -> Shallow (Three (y, z, x)) | Shallow (Three (y, z, z')) -> _deep 4 (Two (y, z)) _empty (Two (z', x)) | Deep {r= Zero; _} -> assert false | Deep {s; f; m; r= One y} -> _deep (s + 1) f m (Two (y, x)) | Deep {s; f; m; r= Two (y, z)} -> _deep (s + 1) f m (Three (y, z, x)) | Deep {s; f; m= (lazy q'); r= Three (y, z, z')} -> _deep (s + 1) f (lazy (push q' (y, z))) (Two (z', x)) let map_last_digit f = function | Zero -> Zero | One x -> One (f x) | Two (x, y) -> Two (x, f y) | Three (x, y, z) -> Three (x, y, f z) let map_last : 'a. ('a -> 'a) -> 'a t -> 'a t = fun f -> function | Shallow v -> Shallow (map_last_digit f v) | Deep ({r; _} as deep) -> Deep {deep with r= map_last_digit f r} let rec shift : 'a. 'a t -> 'a * 'a t = fun q -> match q with | Shallow Zero -> raise Empty | Shallow (One x) -> (x, empty) | Shallow (Two (x, y)) -> (x, Shallow (One y)) | Shallow (Three (x, y, z)) -> (x, Shallow (Two (y, z))) | Deep {f= Zero; _} -> assert false | Deep {s; f= One x; m= (lazy q'); r} -> if is_empty q' then (x, Shallow r) else let (y, z), q' = shift q' in (x, _deep (s - 1) (Two (y, z)) (Lazy.from_val q') r) | Deep {s; f= Two (x, y); m; r} -> (x, _deep (s - 1) (One y) m r) | Deep {s; f= Three (x, y, z); m; r} -> (x, _deep (s - 1) (Two (y, z)) m r) let rec cons : 'a. 'a t -> 'a -> 'a t = fun q x -> match q with | Shallow Zero -> Shallow (One x) | Shallow (One y) -> Shallow (Two (x, y)) | Shallow (Two (y, z)) -> Shallow (Three (x, y, z)) | Shallow (Three (y, z, z')) -> _deep 4 (Two (x, y)) _empty (Two (z, z')) | Deep {f= Zero; _} -> assert false | Deep {s; f= One y; m; r} -> _deep (s + 1) (Two (x, y)) m r | Deep {s; f= Two (y, z); m; r} -> _deep (s + 1) (Three (x, y, z)) m r | Deep {s; f= Three (y, z, z'); m= (lazy q'); r} -> _deep (s + 1) (Two (x, y)) (lazy (cons q' (z, z'))) r let _digit_to_seq d k = match d with | Zero -> () | One x -> k x | Two (x, y) -> k x ; k y | Three (x, y, z) -> k x ; k y ; k z type 'a sequence = ('a -> unit) -> unit let rec to_seq : 'a. 'a t -> 'a sequence = fun q k -> match q with | Shallow d -> _digit_to_seq d k | Deep {f; m= (lazy q'); r; _} -> _digit_to_seq f k ; to_seq q' (fun (x, y) -> k x ; k y) ; _digit_to_seq r k let iter f q = to_seq q f let _fold_digit f acc d = match d with | Zero -> acc | One x -> f acc x | Two (x, y) -> f (f acc x) y | Three (x, y, z) -> f (f (f acc x) y) z let rec fold : 'a 'b. ('b -> 'a -> 'b) -> 'b -> 'a t -> 'b = fun func acc q -> match q with | Shallow d -> _fold_digit func acc d | Deep {f; m= (lazy q'); r; _} -> let acc = _fold_digit func acc f in let acc = fold (fun acc (x, y) -> func (func acc x) y) acc q' in _fold_digit func acc r let to_list q = let l = ref [] in to_seq q (fun x -> l := x :: !l) ; List.rev !l let of_list l = List.fold_left push empty l let pp ppv ppf q = Fmt.pf ppf "[ %a ]" (Fmt.hvbox (Fmt.list ~sep:(Fmt.unit ";@ ") ppv)) (to_list q)