package batteries
A community-maintained standard library extension
Install
Dune Dependency
Authors
Maintainers
Sources
v3.9.0.tar.gz
md5=ea26b5c72e6731e59d856626049cca4d
sha512=55975b62c26f6db77433a3ac31f97af609fc6789bb62ac38b267249c78fd44ff37fe81901f1cf560857b9493a6046dd37b0d1c0234c66bd59e52843aac3ce6cb
doc/src/batteries.unthreaded/batLazyList.ml.html
Source file batLazyList.ml
1 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 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793
(* * LazyListLabels - lazily-computed lists * Copyright (C) 2008 David Teller * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version, * with the special exception on linking described in file LICENSE. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *) ##V>=5##module Pervasives = Stdlib (*$inject ##V>=5##module Pervasives = Stdlib *) (** {6 Exceptions} *) exception No_more_elements exception Empty_list exception Invalid_index of int exception Different_list_size of string (** {6 Types} *) type 'a node_t = | Nil | Cons of 'a * 'a t and 'a t = ('a node_t) Lazy.t type 'a enumerable = 'a t type 'a mappable = 'a t (** {6 Access} *) let lazy_from_val v = ##V<5## Lazy.lazy_from_val v ##V>=5## Lazy.from_val v let nil = lazy_from_val Nil let next l = Lazy.force l let cons h t = lazy_from_val (Cons(h, t)) let ( ^:^ ) = cons let get l = match next l with | Nil -> None | Cons (x, rest) -> Some (x, rest) let peek l = match next l with | Nil -> None | Cons (x, _) -> Some x (** {6 Constructors} *) let from_while f = let rec aux () = lazy ( match f () with | None -> Nil | Some x -> Cons (x, aux ()) ) in aux () let from f = let f' () = try Some (f ()) with No_more_elements -> None in from_while f' let seq data next cond = let rec aux data = if cond data then Cons (data, lazy (aux (next data))) else Nil in lazy (aux data) let unfold (data:'b) (next: 'b -> ('a * 'b) option) = let rec aux data = match next data with | Some(a,b) -> Cons(a, lazy (aux b)) | None -> Nil in lazy (aux data) let from_loop (data:'b) (next:'b -> ('a * 'b)) : 'a t= let f' data = try Some (next data) with No_more_elements -> None in unfold data f' let init n f = let rec aux i = if i < n then lazy (Cons (f i, aux ( i + 1 ) ) ) else nil in if n < 0 then invalid_arg "LazyList.init" else aux 0 let make n x = let rec aux i = if i < n then lazy (Cons (x, aux ( i + 1 ) ) ) else nil in if n < 0 then invalid_arg "LazyList.make" else aux 0 (** {6 Iterators} *) let iter f l = let rec aux l = match next l with | Cons (x, t) -> (ignore (f x); aux t) | Nil -> () in aux l let iteri f l = let rec aux i l = match next l with | Cons (x, t) -> (f i x; aux (i + 1) t) | Nil -> () in aux 0 l let map f l = let rec aux rest = match next rest with | Cons (x, (t : 'a t)) -> Cons (f x, lazy (aux t)) | Nil -> Nil in lazy (aux l) let mapi f l = let rec aux rest i = match next rest with | Cons (x, (t : 'a t)) -> Cons (f i x, lazy (aux t ( i + 1 ) )) | Nil -> Nil in lazy (aux l 0) let fold_left f init l = let rec aux acc rest = match next rest with | Cons (x, t) -> aux (f acc x) t | Nil -> acc in aux init l let fold_right f init l = let rec aux rest = match next rest with | Cons (x, t) -> f x (aux t) | Nil -> init in aux l let eager_fold_right f l init = fold_right f init l let lazy_fold_right f l init = let rec aux rest = lazy begin match next rest with | Cons (x, t) -> f x (aux t) | Nil -> Lazy.force init end in aux l (** {6 Finding}*) let may_find p l = let rec aux l = match next l with | Nil -> None | Cons (x, t) -> if p x then Some x else aux t in aux l let may_rfind p l = let rec aux l acc = match next l with | Nil -> acc | Cons (x, t) -> aux t (if p x then Some x else acc) in aux l None let may_findi p l = let rec aux l i = match next l with | Nil -> None | Cons (x, _) when p i x -> Some (i, x) | Cons (_, t) -> aux t (i+1) in aux l 0 let may_rfindi p l = let rec aux l acc i = match next l with | Nil -> acc | Cons (x, t) -> aux t (if p i x then Some (i, x) else acc) (i+1) in aux l None 0 let find_exn p e l = BatOption.get_exn (may_find p l) e let rfind_exn p e l = BatOption.get_exn (may_rfind p l) e let find p l = find_exn p Not_found l let rfind p l = rfind_exn p Not_found l let findi p l = BatOption.get_exn (may_findi p l) Not_found let rfindi p l = BatOption.get_exn (may_rfindi p l) Not_found let index_of e l = match may_findi (fun _ x -> e = x) l with | None -> None | Some (i, _) -> Some i let rindex_of e l = match may_rfindi (fun _ x -> e = x) l with | None -> None | Some (i, _) -> Some i let index_ofq e l = match may_findi (fun _ x -> e == x) l with | None -> None | Some (i, _) -> Some i let rindex_ofq e l = match may_rfindi (fun _ x -> e == x) l with | None -> None | Some (i, _) -> Some i (** {6 Common functions}*) let length l = fold_left (fun n _ -> n + 1) 0 l let is_empty l = match next l with | Nil -> true | Cons _ -> false let would_at_fail n = let rec aux l i = match next l with | Nil -> true | Cons (_, _) when i = 0 -> false | Cons (_, t) -> aux t (i - 1) in aux n let hd list = match next list with | Cons (x, _) -> x | Nil -> raise Empty_list let first = hd let last l = let rec aux acc l = match next l with | Nil -> acc | Cons(x, t) -> aux (Some x) t in match aux None l with | None -> raise Empty_list | Some x -> x let tl list = match next list with | Cons (_, t) -> t | Nil -> raise Empty_list let at list n = let rec aux list i = match ((next list), i) with | (Cons (x, _), 0) -> x | (Cons (_, t), _) -> aux t (i - 1) | (Nil, _) -> raise (Invalid_index n) in if n < 0 then raise (Invalid_index n) else aux list n let nth = at let rev list = fold_left (fun acc x -> lazy_from_val (Cons (x, acc))) nil list (**Revert a list, convert it to a lazy list. Used as an optimisation.*) let rev_of_list (list:'a list) = List.fold_left (fun acc x -> lazy_from_val (Cons (x, acc))) nil list let eager_append (l1 : 'a t) (l2 : 'a t) = let rec aux list = match next list with | Cons (x, t) -> cons x (aux t) | Nil -> l2 in aux l1 let rev_append (l1 : 'a t) (l2 : 'a t) = let rec aux list acc = match next list with | Cons (x, t) -> aux t (lazy_from_val (Cons (x, acc))) | Nil -> acc in aux l1 l2 (**Revert a list, convert it to a lazy list and append it. Used as an optimisation.*) let rev_append_of_list (l1 : 'a list) (l2 : 'a t) : 'a t = let rec aux list acc = match list with | [] -> acc | h::t -> aux t (cons h acc) in aux l1 l2 let append (l1 : 'a t) (l2 : 'a t) = let rec aux list = match next list with | Cons (x, (t : 'a t)) -> Cons (x, lazy (aux t)) | _ -> Lazy.force l2 in lazy (aux l1) (*$T append to_list (append (of_list [1;2]) (of_list [3;4])) = [1;2;3;4] ignore (append (lazy (failwith "lazy cell")) nil); true hd (append (cons () nil) (lazy (failwith "lazy cell"))); true *) let ( ^@^ ) = append let flatten (lol : ('a t) list) = ListLabels.fold_left ~init: nil ~f: append lol let concat lol = lazy_fold_right (fun li rest -> Lazy.force (append li rest)) lol nil (*$T concat to_list (concat (of_list (List.map of_list [[1;2]; [3]; [4;5]; []; [6]; []; []]))) = [1;2;3;4;5;6] ignore (concat (lazy (Cons ((let () = failwith "foo" in nil), nil)))); true *) (** {6 Combinatorics} *) let combinations l = let rec gen l = match l with | [] -> cons [] nil | x::l' -> lazy (let tl = gen l' in let node = append tl (map (fun l -> x::l) tl) in Lazy.force node) in gen l (*$T combinations List.sort Legacy.compare (to_list (combinations [1;2;3])) = \ [[]; [1]; [1;2]; [1;2;3]; [1;3]; [2]; [2;3]; [3]] to_list (combinations []) = [[]] List.sort Legacy.compare (to_list (combinations [1])) = [[]; [1]] *) let permutations l = (* do a choice in [l]. [right] contain elements not to choose from. *) let rec choose_first among right = match among with | [] -> cons [] nil | [x] -> perms_starting_with x right | x::among' -> (* choose [x], or don't (in which case put it in [right]) *) append (perms_starting_with x (among' @ right)) (choose_first among' (x::right)) (* all permutations of [l], prefixed with [x] *) and perms_starting_with x l = map (fun l -> x :: l) (choose_first l []) in choose_first l [] (*$T permutations List.sort Legacy.compare (to_list (permutations [1;2;3])) = \ [[1;2;3]; [1;3;2]; [2;1;3]; [2;3;1]; [3;1;2]; [3;2;1]] to_list (permutations []) = [[]] to_list (permutations [1]) = [[1]] *) (** {6 Conversions} *) (** Eager conversion to list. *) let to_list l = fold_right (fun x acc -> x :: acc) [] l (** Lazy conversion to stream. *) let to_stream l = let rec aux rest = match next rest with | Cons (x, t) -> Stream.icons x (Stream.slazy (fun _ -> aux t)) | Nil -> Stream.sempty in aux l (** Eager conversion to array. *) let to_array l = Array.of_list (to_list l) let enum l = let rec aux l = let reference = ref l in BatEnum.make ~next:(fun () -> match next !reference with | Cons(x,t) -> reference := t; x | Nil -> raise BatEnum.No_more_elements ) ~count:(fun () -> length !reference) ~clone:(fun () -> aux !reference) in aux l (** Lazy conversion from lists Albeit slower than eager conversion, this is the default mechanism for converting from regular lists to lazy lists. This for two reasons : * if you're using lazy lists, total speed probably isn't as much an issue as start-up speed * this will let you convert regular infinite lists to lazy lists. *) let of_list l = let rec aux = function | [] -> nil | h :: t -> lazy (Cons (h, aux t)) in aux l (** Lazy conversion from stream. *) let of_stream s = let rec aux s = let (__strm : _ Stream.t) = s in match Stream.peek __strm with | Some h -> (Stream.junk __strm; lazy (Cons (h, aux s))) | None -> nil in aux s (** Eager conversion from lists *) let eager_of_list l = ListLabels.fold_right ~init: nil ~f: (fun x acc -> lazy_from_val (Cons (x, acc))) l (** Eager conversion from array *) let of_array l = ArrayLabels.fold_right ~init: nil ~f: (fun x acc -> lazy_from_val (Cons (x, acc))) l (** Lazy conversion from enum *) let of_enum e = let rec aux () = lazy (match BatEnum.get e with | Some x -> Cons (x, aux () ) | None -> Nil ) in aux () (** {6 Predicates} *) let filter f l = let rec next_true l = match next l with (*Compute the next accepted predicate without thunkification*) | Cons (x, l) when not (f x) -> next_true l | l -> l in let rec aux l = lazy(match next_true l with | Cons (x, l) -> Cons (x, aux l) | Nil -> Nil) in aux l let filter_map f l = let rec next_true l = match next l with (*Compute the next accepted predicate without thunkification*) | Cons (x, l) -> begin match f x with | Some v -> Some (v, l) | None -> next_true l end | Nil -> None in let rec aux l = lazy(match next_true l with | Some (x, l) -> Cons (x, aux l) | None -> Nil) in aux l (*let filter f l = let rec aux rest = match next rest with | Cons (x, t) when f x -> Cons (x, lazy (aux t)) | Cons (_, t) -> aux t | Nil -> Nil in lazy (aux l)*) let exists f l = let rec aux rest = match next rest with | Cons (x, _) when f x -> true | Cons (_, t) -> aux t | Nil -> false in aux l (*$T exists exists (fun x -> x = 3) (append (of_list [0;1;2]) (map (fun () -> 3) eternity)) not (exists (fun x -> x < 0) (init 100 (fun i -> i))) *) let for_all f l = let rec aux rest = match next rest with | Cons (x, t) when f x -> aux t | Cons _ -> false | Nil -> true in aux l (*$T for_all not (for_all (fun x -> x <> 3) (append (of_list [0;1;2]) (map (fun () -> 3) eternity))) for_all (fun x -> x >= 0) (init 100 (fun i -> i)) *) let range a b = let rec increasing lo hi = if lo > hi then nil else lazy (Cons (lo, increasing (lo + 1) hi)) in (* and decreasing lo hi = if lo > hi then nil else lazy (Cons hi (decreasing lo (hi - 1)))*) if b >= a then increasing a b else (*decreasing b a*) nil let drop n l = let rec aux l i = if i = 0 then l else match next l with | Nil -> raise (Invalid_index n) | Cons(_, t) -> aux t (i - 1) in aux l n let split_at n li = let last_n = ref n in let last_li = ref li in let rec take n li = last_n := n; last_li := li; if n = 0 then lazy Nil else lazy (match (Lazy.force li) with | Nil -> Nil | Cons (x, xs) -> Cons (x, take (n - 1) xs)) in take n li, lazy (Lazy.force (drop !last_n !last_li)) let split_nth = split_at let mem e = exists (( = ) e) let memq e = exists (( == ) e ) let assoc e l = snd (find (fun (a,_) -> a = e) l) let assq e l = snd (find (fun (a,_) -> a == e) l) let mem_assoc e l = BatOption.is_some (may_find (fun (a, _) -> a = e) l) let mem_assq e l = BatOption.is_some (may_find (fun (a, _) -> a == e) l) (* let rec aux rest = match next rest with | Cons (h, t) -> (match f h with | None -> lazy (aux t) | Some x -> cons x (lazy (aux t))) | Nil -> Nil in lazy (aux l)*) let unique ?(cmp = compare) l = let set = ref (BatMap.PMap.create cmp) in let should_keep x = if BatMap.PMap.mem x !set then false else ( set := BatMap.PMap.add x true !set; true ) in (* use a stateful filter to remove duplicate elements *) filter should_keep l let unique_eq ?(eq = (=)) l = let rec next_true l = match next l with (*Compute the next accepted predicate without thunkification*) | Cons (x, l) when exists (eq x) l -> next_true l | l -> l in let rec aux l = lazy(match next_true l with | Cons (x, l) -> Cons (x, aux l) | Nil -> Nil) in aux l let remove_if p l = let rec aux acc l = match next l with | Nil -> rev_of_list acc | Cons(h,t) when p h -> rev_append_of_list acc t | Cons(h,t) -> aux (h::acc) t in aux [] l let remove_all_such p l = filter_map (fun y -> if p y then None else Some y) l let remove x l = remove_if ( ( = ) x ) l let remove_all x l = remove_all_such ( ( = ) x ) l (** An infinite list of nothing *) let rec eternity = lazy (Cons ((), eternity)) let take n l = fst (split_at n l) let drop_while p = let rec aux l = match next l with | Nil -> nil | Cons(h,t) when p h -> aux t | Cons(_,_) -> l in aux (* TODO: make lazy *) let take_while p = let rec aux acc l = match next l with | Cons(h,t) when p h -> aux (h::acc) t | Cons _ | Nil -> rev_of_list acc in aux [] let sort ?(cmp=Pervasives.compare) l = of_list (List.sort cmp (to_list l)) let stable_sort cmp l = of_list (List.stable_sort cmp (to_list l)) let map2 f l1 l2 = let rec aux l1 l2 = match (next l1, next l2) with | (Cons (h1, t1), Cons(h2, t2)) -> lazy (Cons (f h1 h2, aux t1 t2)) | (Nil, Nil) -> nil | (Cons _, Nil) | (Nil, Cons _) -> raise (Different_list_size "LazyList.map2") in aux l1 l2 let iter2 f l1 l2 = let rec aux l1 l2 = match (next l1, next l2) with | (Cons (h1, t1), Cons(h2, t2)) -> f h1 h2; aux t1 t2 | (Nil, Nil) -> () | (Cons _, Nil) | (Nil, Cons _) -> raise (Different_list_size "LazyList.iter2") in aux l1 l2 let fold_left2 f acc l1 l2 = let rec aux acc l1 l2 = match (next l1, next l2) with | (Cons (h1, t1), Cons(h2, t2)) -> aux (f acc h1 h2) t1 t2 | (Nil, Nil) -> acc | (Cons _, Nil) | (Nil, Cons _) -> raise (Different_list_size "LazyList.fold_left2") in aux acc l1 l2 let fold_right2 f l1 l2 acc = let rec aux l1 l2 = match (next l1, next l2) with | (Cons (h1, t1), Cons(h2, t2)) -> f h1 h2 (aux t1 t2) | (Nil, Nil) -> acc | (Cons _, Nil) | (Nil, Cons _) -> raise (Different_list_size "LazyList.fold_right2") in aux l1 l2 let for_all2 p l1 l2 = let rec aux l1 l2 = match (next l1, next l2) with | (Cons (h1, t1), Cons(h2, t2)) -> p h1 h2 && (aux t1 t2) | (Nil, Nil) -> true | (Cons _, Nil) | (Nil, Cons _) -> raise (Different_list_size "LazyList.for_all2") in aux l1 l2 let equal eq l1 l2 = let rec aux l1 l2 = match (next l1, next l2) with | (Cons (h1, t1), Cons (h2, t2)) -> eq h1 h2 && (aux t1 t2) | (Nil, Nil) -> true | (Cons _, Nil) | (Nil, Cons _) -> false in aux l1 l2 (*$T equal equal (equal (=)) (init 3 (range 0)) (init 3 (range 0)) not (equal (equal (=)) (of_list [(of_list [0; 1; 2])]) (of_list [(of_list [0; 42; 2])])) not (equal (=) (range 0 2) (range 0 3)) not (equal (=) (range 0 3) (range 0 2)) *) let exists2 p l1 l2 = let rec aux l1 l2 = match (next l1, next l2) with | (Cons (h1, t1), Cons(h2, t2)) -> p h1 h2 || (aux t1 t2) | (Nil, Nil) -> false | (Cons _, Nil) | (Nil, Cons _) -> raise (Different_list_size "LazyList.exists2") in aux l1 l2 let combine l1 l2 = let rec aux l1 l2 = match (next l1, next l2) with | (Cons(h1, t1), Cons(h2, t2)) -> lazy (Cons ((h1, h2), ( aux t1 t2 ))) | (Nil, Nil ) -> nil | (Cons _, Nil) | (Nil, Cons _) -> raise (Different_list_size "LazyList.combine") in aux l1 l2 let uncombine l = let (l1, l2) = BatEnum.uncombine (enum l) in (of_enum l1, of_enum l2) (*let uncombine l = let rec aux l = match next l with | Cons ((h1, h2), t) -> lazy (let (t1, t2) = aux t in Cons (h1, t1), Cons(h2, t2)) | Nil -> lazy (Nil, Nil) in aux l*) (*let uncombine l = unfold l (fun l -> match peek l with | None -> None | Cons (h1, h2), t*) let print ?(first="[^") ?(last="^]") ?(sep="; ") print_a out t = BatEnum.print ~first ~last ~sep print_a out (enum t) module Infix = struct let ( ^:^ ), ( ^@^ ) = ( ^:^ ), ( ^@^ ) end module Exceptionless = struct (** Exceptionless counterparts for error-raising operations*) let find = may_find let rfind = may_rfind let findi = may_findi let rfindi = may_rfindi let at list n = let rec aux list i = match (next list, i) with | (Cons (x, _), 0) -> `Ok x | (Cons (_, t), _) -> aux t (i - 1) | (Nil, _) -> `Invalid_index n in if n < 0 then `Invalid_index n else aux list n let assoc a (l:'a t) = try Some (assoc a l) with Not_found -> None let assq a l = try Some (assq a l) with Not_found -> None let split_at n l = try `Ok (split_at n l) with Not_found -> `Invalid_index n end module Labels = struct let iter ~f x = iter f x let iter2 ~f x = iter2 f x let iteri ~f x = iteri f x let map ~f x = map f x let map2 ~f x = map2 f x let mapi ~f x = mapi f x let filter ~f = filter f let exists ~f = exists f let exists2 ~f = exists2 f let for_all ~f = for_all f let for_all2 ~f = for_all2 f let filter_map ~f = filter_map f let find ~f = find f let findi ~f = findi f let rfind ~f = rfind f let rfindi ~f = rfindi f let find_exn ~f = find_exn f let rfind_exn ~f = rfind_exn f let remove_if ~f = remove_if f let remove_all_such ~f= remove_all_such f let take_while ~f= take_while f let drop_while ~f= drop_while f let fold_left ~f ~init = fold_left f init let fold_right ~f ~init = fold_right f init let fold_left2 ~f ~init = fold_left2 f init let fold_right2 ~f l1 l2 ~init = fold_right2 f l1 l2 init module Exceptionless = struct let find ~f = Exceptionless.find f let rfind ~f = Exceptionless.rfind f let findi ~f = Exceptionless.findi f let rfindi ~f = Exceptionless.rfindi f let assq = Exceptionless.assq let assoc = Exceptionless.assoc let at = Exceptionless.at let split_at = Exceptionless.split_at end end
sectionYPositions = computeSectionYPositions($el), 10)"
x-init="setTimeout(() => sectionYPositions = computeSectionYPositions($el), 10)"
>