Module Ext_list

let map_combine: list('a) => list('b) => ('a => 'c) => list(('c, 'b));
let combine_array: array('a) => list('b) => ('a => 'c) => list(('c, 'b));
let combine_array_append: array('a) => list('b) => list(('c, 'b)) => ('a => 'c) => list(('c, 'b));
let map_snd: list(('a, 'b)) => ('b => 'c) => list(('a, 'c));
let map_last: list('a) => (bool => 'a => 'b) => list('b);

map_last f xs will pass true to f for the last element, false otherwise. For empty list, it returns empty

let append_one: list('a) => 'a => list('a);
let fold_right3: list('a) => list('b) => list('c) => 'd => ('a => 'b => 'c => 'd => 'd) => 'd;
let fold_left_with_offset: list('a) => 'acc => int => ('a => 'acc => int => 'acc) => 'acc;
let same_length: list('a) => list('b) => bool;
let split_at: list('a) => int => (list('a), list('a));

split_at n l will split l into two lists a,b, a will be of length n, otherwise, it will raise

let split_at_last: list('a) => (list('a), 'a);

split_at_last l It is equivalent to split_at (List.length l - 1) l

let filter_mapi: list('a) => ('a => int => option('b)) => list('b);
let length_ge: list('a) => int => bool;
length xs = length ys + n 

input n should be positive TODO: input checking

let length_larger_than_n: list('a) => list('a) => int => bool;
let stable_group: list('a) => ('a => 'a => bool) => list(list('a));

stable_group eq lst Example: Input:

stable_group (=) [1;2;3;4;3]

Output:

[[1];[2];[4];[3;3]]

TODO: this is O(n^2) behavior which could be improved later

let find_first_not: list('a) => ('a => bool) => option('a);

find_first_not p lst if all elements in lst pass, return None otherwise return the first element e as Some e which fails the predicate

find_opt f l returns None if all return None, otherwise returns the first one.

let find_opt: list('a) => ('a => option('b)) => option('b);
let find_def: list('a) => ('a => option('b)) => 'b => 'b;
let rev_iter: list('a) => ('a => unit) => unit;
let for_all_snd: list(('a, 'b)) => ('b => bool) => bool;
let for_all2_no_exn: list('a) => list('b) => ('a => 'b => bool) => bool;

for_all2_no_exn p xs ys return true if all satisfied, false otherwise or length not equal

let split_map: list('a) => ('a => ('b, 'c)) => (list('b), list('c));

f is applied follow the list order

let sort_via_array: list('a) => ('a => 'a => int) => list('a);
let sort_via_arrayf: list('a) => ('a => 'a => int) => ('a => 'b) => list('b);
let assoc_by_string: list((string, 'a)) => string => option('a) => 'a;

assoc_by_string default key lst if key is found in the list return that val, other unbox the default, otherwise assert false

let assoc_by_int: list((int, 'a)) => int => option('a) => 'a;
let concat_append: list(list('a)) => list('a) => list('a);