Module Belt.List
Utilities for List data type
Utilities for List data type.
This module is compatible with original ocaml stdlib. In general, all functions comes with the original stdlib also applies to this collection, however, this module provides faster and stack safer utilities
type 'a t = 'a listtype t('a) = list('a);'a tt('a) is compatible with built-in list type
val length : 'a t -> intlet length: t('a) => int;length xs
returns the length of the list xs
val size : 'a t -> intlet size: t('a) => int;See length
val head : 'a t -> 'a optionlet head: t('a) => option('a);head xs returns None if xs is the empty list, otherwise it returns Some value where value is the first element in the list.
head [] = None ;;
head [1;2;3] = Some 1 ;;head([]) == None;
head([1, 2, 3]) == Some(1);val headExn : 'a t -> 'alet headExn: t('a) => 'a;headExn xs
See head
raise an exception if xs is empty
val tail : 'a t -> 'a t optionlet tail: t('a) => option(t('a));tail xs returns None if xs is empty; otherwise it returns Some xs2 where xs2 is everything except the first element of xs;
tail [] = None;;
tail [1;2;3;4] = Some [2;3;4];;tail([]) == None;
tail([1, 2, 3, 4]) == Some([2, 3, 4]);val tailExn : 'a t -> 'a tlet tailExn: t('a) => t('a);tailExn xs
See tail
raise an exception if xs is empty
val add : 'a t -> 'a -> 'a tlet add: t('a) => 'a => t('a);add xs y adds y to the beginning of list xs
add [1] 3 = [3;1];;add([1], 3) == [3, 1];val get : 'a t -> int -> 'a optionlet get: t('a) => int => option('a);get xs n
return the nth element in xs, or None if n is larger than the length
get [0;3;32] 2 = Some 32 ;;
get [0;3;32] 3 = None;;get([0, 3, 32], 2) == Some(32);
get([0, 3, 32], 3) == None;val getExn : 'a t -> int -> 'alet getExn: t('a) => int => 'a;getExn xs n
See get
raise an exception if n is larger than the length
val make : int -> 'a -> 'a tlet make: int => 'a => t('a);make n v
- return a list of length
nwith each element filled with valuev - return the empty list if
nis negative
make 3 1 = [1;1;1]make(3, 1) == [1, 1, 1];val makeByU : int -> (int -> 'a) Js.Fn.arity1 -> 'a tlet makeByU: int => Js.Fn.arity1((int => 'a)) => t('a);val makeBy : int -> (int -> 'a) -> 'a tlet makeBy: int => (int => 'a) => t('a);makeBy n f
- return a list of length
nwith elementiinitialized withf i - return the empty list if
nis negative
makeBy 5 (fun i -> i) = [0;1;2;3;4];;
makeBy 5 (fun i -> i * i) = [0;1;4;9;16];;makeBy(5, i => i) == [0, 1, 2, 3, 4];
makeBy(5, i => i * i) == [0, 1, 4, 9, 16];val shuffle : 'a t -> 'a tlet shuffle: t('a) => t('a);shuffle xs
returns a new list in random order
val drop : 'a t -> int -> 'a t optionlet drop: t('a) => int => option(t('a));drop xs n
return the list obtained by dropping the first n elements, or None if xs has fewer than n elements
drop [1;2;3] 2 = Some [3];;
drop [1;2;3] 3 = Some [];;
drop [1;2;3] 4 = None;;drop([1, 2, 3], 2) == Some([3]);
drop([1, 2, 3], 3) == Some([]);
drop([1, 2, 3], 4) == None;val take : 'a t -> int -> 'a t optionlet take: t('a) => int => option(t('a));take xs n
return a list with the first n elements from xs, or None if xs has fewer than n elements
take [1;2;3] 1 = Some [1];;
take [1;2;3] 2 = Some [1;2];;
take [1;2;3] 4 = None;;take([1, 2, 3], 1) == Some([1]);
take([1, 2, 3], 2) == Some([1, 2]);
take([1, 2, 3], 4) == None;val splitAt : 'a t -> int -> ('a list * 'a list) optionlet splitAt: t('a) => int => option((list('a), list('a)));splitAt xs n split the list xs at position n return None when the length of xs is less than n
splitAt [0;1;2;3;4] 2 = Some ([0;1], [2;3;4])splitAt([0, 1, 2, 3, 4], 2) == Some(([0, 1], [2, 3, 4]));val concat : 'a t -> 'a t -> 'a tlet concat: t('a) => t('a) => t('a);concat xs ys
returns the list obtained by adding ys after xs
concat [1;2;3] [4;5] = [1;2;3;4;5]concat([1, 2, 3], [4, 5]) == [1, 2, 3, 4, 5];val concatMany : 'a t array -> 'a tlet concatMany: array(t('a)) => t('a);concatMany a return the list obtained by concatenating in order all the lists in array a
concatMany [| [1;2;3] ; []; [3]; [4] |] = [1;2;3;3;4]concatMany([|[1, 2, 3], [], [3], [4]|]) == [1, 2, 3, 3, 4];val reverseConcat : 'a t -> 'a t -> 'a tlet reverseConcat: t('a) => t('a) => t('a);reverseConcat xs ys is equivalent to concat (reverse xs) ys
reverseConcat [1;2] [3;4] = [2;1;3;4]reverseConcat([1, 2], [3, 4]) == [2, 1, 3, 4];val flatten : 'a t t -> 'a tlet flatten: t(t('a)) => t('a);flatten ls return the list obtained by concatenating in order all the lists in list ls
flatten [ [1;2;3] ; []; [3]; [4] ] = [1;2;3;3;4]flatten([[1, 2, 3], [], [3], [4]]) == [1, 2, 3, 3, 4];val mapU : 'a t -> ('a -> 'b) Js.Fn.arity1 -> 'b tlet mapU: t('a) => Js.Fn.arity1(('a => 'b)) => t('b);val map : 'a t -> ('a -> 'b) -> 'b tlet map: t('a) => ('a => 'b) => t('b);map xs f
return the list obtained by applying f to each element of xs
map [1;2] (fun x-> x + 1) = [3;4]map([1, 2], x => x + 1) == [3, 4];val zip : 'a t -> 'b t -> ('a * 'b) tlet zip: t('a) => t('b) => t(('a, 'b));zip xs ys
returns a list of pairs from the two lists with the length of the shorter list
zip [1;2] [3;4;5] = [(1,3); (2,4)]zip([1, 2], [3, 4, 5]) == [(1, 3), (2, 4)];val zipByU : 'a t -> 'b t -> ('a -> 'b -> 'c) Js.Fn.arity2 -> 'c tlet zipByU: t('a) => t('b) => Js.Fn.arity2(('a => 'b => 'c)) => t('c);val zipBy : 'a t -> 'b t -> ('a -> 'b -> 'c) -> 'c tlet zipBy: t('a) => t('b) => ('a => 'b => 'c) => t('c);zipBy xs ys f
See zip
Equivalent to zip xs ys |> List.map (fun (x,y) -> f x y)
zipBy [1;2;3] [4;5] (fun a b -> 2 * a + b) = [6;9];;zipBy([1, 2, 3], [4, 5], (a, b) => 2 * a + b) == [6, 9];val mapWithIndexU : 'a t -> (int -> 'a -> 'b) Js.Fn.arity2 -> 'b tlet mapWithIndexU: t('a) => Js.Fn.arity2((int => 'a => 'b)) => t('b);val mapWithIndex : 'a t -> (int -> 'a -> 'b) -> 'b tlet mapWithIndex: t('a) => (int => 'a => 'b) => t('b);mapWithIndex xs f applies f to each element of xs. Function f takes two arguments: the index starting from 0 and the element from xs.
mapWithIndex [1;2;3] (fun i x -> i + x) =
[0 + 1; 1 + 2; 2 + 3 ]mapWithIndex([1, 2, 3], (i, x) => i + x) == [0 + 1, 1 + 2, 2 + 3];val fromArray : 'a array -> 'a tlet fromArray: array('a) => t('a);fromArray arr converts the given array to a list
fromArray [|1;2;3|] = [1;2;3]fromArray([|1, 2, 3|]) == [1, 2, 3];val toArray : 'a t -> 'a arraylet toArray: t('a) => array('a);toArray xs converts the given list to an array
toArray [1;2;3] = [|1;2;3|]toArray([1, 2, 3]) == [|1, 2, 3|];val reverse : 'a t -> 'a tlet reverse: t('a) => t('a);reverse xs returns a new list whose elements are those of xs in reverse order.
reverse [1;2;3] = [3;2;1]reverse([1, 2, 3]) == [3, 2, 1];val mapReverseU : 'a t -> ('a -> 'b) Js.Fn.arity1 -> 'b tlet mapReverseU: t('a) => Js.Fn.arity1(('a => 'b)) => t('b);val mapReverse : 'a t -> ('a -> 'b) -> 'b tlet mapReverse: t('a) => ('a => 'b) => t('b);mapReverse xs f
Equivalent to reverse (map xs f)
mapReverse [3;4;5] (fun x -> x * x) = [25;16;9];;mapReverse([3, 4, 5], x => x * x) == [25, 16, 9];val forEachU : 'a t -> ('a -> 'b) Js.Fn.arity1 -> unitlet forEachU: t('a) => Js.Fn.arity1(('a => 'b)) => unit;val forEach : 'a t -> ('a -> 'b) -> unitlet forEach: t('a) => ('a => 'b) => unit;forEach xs f Call f on each element of xs from the beginning to end. f returns unit, so no new array is created. Use foreach when you are primarily concerned with repetitively creating side effects.
forEach ["a";"b";"c"] (fun x -> Js.log("Item: " ^ x));;
(* prints:
Item: a
Item: b
Item: c
*)
let us = ref 0;;
forEach [1;2;3;4] (fun x -> us := !us + x);;
!us = 1 + 2 + 3 + 4;;forEach(["a", "b", "c"], x => Js.log("Item: " ++ x));
/* prints:
Item: a
Item: b
Item: c
*/
let us = ref(0);
forEach([1, 2, 3, 4], x => us := us^ + x);
us^ == 1 + 2 + 3 + 4;val forEachWithIndexU : 'a t -> (int -> 'a -> 'b) Js.Fn.arity2 -> unitlet forEachWithIndexU: t('a) => Js.Fn.arity2((int => 'a => 'b)) => unit;val forEachWithIndex : 'a t -> (int -> 'a -> 'b) -> unitlet forEachWithIndex: t('a) => (int => 'a => 'b) => unit;forEachWithIndex xs f
forEach ["a";"b";"c"] (fun i x -> Js.log("Item " ^ (string_of_int i) ^ " is " ^ x));;
(* prints:
Item 0 is a
Item 1 is b
Item 2 is cc
*)
let total = ref 0 ;;
forEachWithIndex [10;11;12;13] (fun i x -> total := !total + x + i);;
!total = 0 + 10 + 1 + 11 + 2 + 12 + 3 + 13;;forEach(["a", "b", "c"], (i, x) =>
Js.log("Item " ++ string_of_int(i) ++ " is " ++ x)
);
/* prints:
Item 0 is a
Item 1 is b
Item 2 is cc
*/
let total = ref(0);
forEachWithIndex([10, 11, 12, 13], (i, x) => total := total^ + x + i);
total^ == 0 + 10 + 1 + 11 + 2 + 12 + 3 + 13;val reduceU : 'a t -> 'b -> ('b -> 'a -> 'b) Js.Fn.arity2 -> 'blet reduceU: t('a) => 'b => Js.Fn.arity2(('b => 'a => 'b)) => 'b;val reduce : 'a t -> 'b -> ('b -> 'a -> 'b) -> 'blet reduce: t('a) => 'b => ('b => 'a => 'b) => 'b;reduce xs f
Applies f to each element of xs from beginning to end. Function f has two parameters: the item from the list and an “accumulator”, which starts with a value of init. reduce returns the final value of the accumulator.
reduce [1;2;3;4] 0 (+) = 10;;
reduce [1;2;3;4] 10 (-) = 0;;
reduce [1;2;3;4] [] add = [4;3;2;1];reduce([1, 2, 3, 4], 0, (+)) == 10;
reduce([1, 2, 3, 4], 10, (-)) == 0;
reduce([1, 2, 3, 4], [], add) == [4, 3, 2, 1];val reduceWithIndexU : 'a t -> 'b -> ('b -> 'a -> int -> 'b) Js.Fn.arity3 -> 'blet reduceWithIndexU:
t('a) =>
'b =>
Js.Fn.arity3(('b => 'a => int => 'b)) =>
'b;val reduceWithIndex : 'a t -> 'b -> ('b -> 'a -> int -> 'b) -> 'blet reduceWithIndex: t('a) => 'b => ('b => 'a => int => 'b) => 'b;reduceWithIndex xs f
Applies f to each element of xs from beginning to end. Function f has three parameters: the item from the list and an “accumulator”, which starts with a value of init and the index of each element. reduceWithIndex returns the final value of the accumulator.
reduceWithIndex [1;2;3;4] 0 (fun acc x i -> acc + x + i) = 16;;reduceWithIndex([1, 2, 3, 4], 0, (acc, x, i) => acc + x + i) == 16;val reduceReverseU : 'a t -> 'b -> ('b -> 'a -> 'b) Js.Fn.arity2 -> 'blet reduceReverseU: t('a) => 'b => Js.Fn.arity2(('b => 'a => 'b)) => 'b;val reduceReverse : 'a t -> 'b -> ('b -> 'a -> 'b) -> 'blet reduceReverse: t('a) => 'b => ('b => 'a => 'b) => 'b;reduceReverse xs f
Works like reduce, except that function f is applied to each item of xs from the last back to the first.
reduceReverse [1;2;3;4] 0 (+) = 10;;
reduceReverse [1;2;3;4] 10 (-) = 0;;
reduceReverse [1;2;3;4] [] add = [1;2;3;4];;reduceReverse([1, 2, 3, 4], 0, (+)) == 10;
reduceReverse([1, 2, 3, 4], 10, (-)) == 0;
reduceReverse([1, 2, 3, 4], [], add) == [1, 2, 3, 4];val mapReverse2U : 'a t -> 'b t -> ('a -> 'b -> 'c) Js.Fn.arity2 -> 'c tlet mapReverse2U: t('a) => t('b) => Js.Fn.arity2(('a => 'b => 'c)) => t('c);val mapReverse2 : 'a t -> 'b t -> ('a -> 'b -> 'c) -> 'c tlet mapReverse2: t('a) => t('b) => ('a => 'b => 'c) => t('c);mapReverse2 xs ys f
equivalent to reverse (zipBy xs ys f)
mapReverse2 [1;2;3] [1;2] (+) = [4;2]mapReverse2([1, 2, 3], [1, 2], (+)) == [4, 2];val forEach2U : 'a t -> 'b t -> ('a -> 'b -> 'c) Js.Fn.arity2 -> unitlet forEach2U: t('a) => t('b) => Js.Fn.arity2(('a => 'b => 'c)) => unit;val forEach2 : 'a t -> 'b t -> ('a -> 'b -> 'c) -> unitlet forEach2: t('a) => t('b) => ('a => 'b => 'c) => unit;forEach2 xs ys f stop with the shorter list
val reduce2U : 'b t -> 'c t -> 'a -> ('a -> 'b -> 'c -> 'a) Js.Fn.arity3 -> 'alet reduce2U:
t('b) =>
t('c) =>
'a =>
Js.Fn.arity3(('a => 'b => 'c => 'a)) =>
'a;val reduce2 : 'b t -> 'c t -> 'a -> ('a -> 'b -> 'c -> 'a) -> 'alet reduce2: t('b) => t('c) => 'a => ('a => 'b => 'c => 'a) => 'a;reduce2 xs ys init f
Applies f to each element of xs and ys from beginning to end. Stops with the shorter list. Function f has three parameters: an “accumulator” which starts with a value of init, an item from xs, and an item from ys. reduce2 returns the final value of the accumulator.
reduce2 [1;2;3] [4;5] 0 (fun acc x y -> acc + x * x + y) = 0 + (1 * 1 + 4) + (2 * 2 + 5);;
reduce2 [1;2;3] [4;5] [] (fun acc x y -> add acc (x + y) = [2 +5;1 + 4 ];; (*add appends at end *)val reduceReverse2U :
'a t ->
'b t ->
'c ->
('c -> 'a -> 'b -> 'c) Js.Fn.arity3 ->
'clet reduceReverse2U:
t('a) =>
t('b) =>
'c =>
Js.Fn.arity3(('c => 'a => 'b => 'c)) =>
'c;val reduceReverse2 : 'a t -> 'b t -> 'c -> ('c -> 'a -> 'b -> 'c) -> 'clet reduceReverse2: t('a) => t('b) => 'c => ('c => 'a => 'b => 'c) => 'c;reduceReverse2 xs ys init f
Applies f to each element of xs and ys from end to beginning. Stops with the shorter list. Function f has three parameters: an “accumulator” which starts with a value of init, an item from xs, and an item from ys. reduce2 returns the final value of the accumulator.
reduceReverse2 [1;2;3] [4;5] 0 (fun acc x y -> acc + x * x + y) = 0 + (1 * 1 + 4) + (2 * 2 + 5);;
reduceReverse2 [1;2;3] [4;5] [] (fun acc x y -> add acc (x + y) = [1 + 4;2 + 5];; (*add appends at end *)val everyU : 'a t -> ('a -> bool) Js.Fn.arity1 -> boollet everyU: t('a) => Js.Fn.arity1(('a => bool)) => bool;val every : 'a t -> ('a -> bool) -> boollet every: t('a) => ('a => bool) => bool;every xs p
returns true if all elements satisfy p, where p is a predicate: a function taking an element and returning a bool.
every [] (fun x -> x mod 2 = 0) = true;;
every [2;4;6] (fun x -> x mod 2 = 0 ) = true;;
every [1;-3;5] (fun x -> x > 0) = false;;every([], x => x mod 2 == 0) == true;
every([2, 4, 6], x => x mod 2 == 0) == true;
every([1, (-3), 5], x => x > 0) == false;val someU : 'a t -> ('a -> bool) Js.Fn.arity1 -> boollet someU: t('a) => Js.Fn.arity1(('a => bool)) => bool;val some : 'a t -> ('a -> bool) -> boollet some: t('a) => ('a => bool) => bool;some xs p
returns true if at least one of the elements in xs satifies p, where p is a predicate: a function taking an element and returning a bool.
some [] (fun x -> x mod 2 = 0) = false ;;
some [1;2;4] (fun x -> x mod 2 = 0) = true;;
some [-1;-3;-5] (fun x -> x > 0) = false;;some([], x => x mod 2 == 0) == false;
some([1, 2, 4], x => x mod 2 == 0) == true;
some([(-1), (-3), (-5)], x => x > 0) == false;val every2U : 'a t -> 'b t -> ('a -> 'b -> bool) Js.Fn.arity2 -> boollet every2U: t('a) => t('b) => Js.Fn.arity2(('a => 'b => bool)) => bool;val every2 : 'a t -> 'b t -> ('a -> 'b -> bool) -> boollet every2: t('a) => t('b) => ('a => 'b => bool) => bool;every2 xs ys p returns true if predicate p xi yi is true for all pairs of elements up to the shorter length (i.e. min (length xs) (length ys))
every2 [1;2;3] [0;1] (>) = true;;
every2 [] [1] (fun x y -> x > y) = true;;
every2 [2;3] [1] (fun x y -> x > y) = true;;
every2 [0;1] [5;0] (fun x y -> x > y) = false;every2([1, 2, 3], [0, 1], (>)) == true;
every2([], [1], (x, y) => x > y) == true;
every2([2, 3], [1], (x, y) => x > y) == true;
every2([0, 1], [5, 0], (x, y) => x > y) == false;val some2U : 'a t -> 'b t -> ('a -> 'b -> bool) Js.Fn.arity2 -> boollet some2U: t('a) => t('b) => Js.Fn.arity2(('a => 'b => bool)) => bool;val some2 : 'a t -> 'b t -> ('a -> 'b -> bool) -> boollet some2: t('a) => t('b) => ('a => 'b => bool) => bool;some2 xs ys p returns true if p xi yi is true for any pair of elements up to the shorter length (i.e. min (length xs) (length ys))
some2 [0;2] [1;0;3] (>) = true ;;
some2 [] [1] (fun x y -> x > y) = false;;
some2 [2;3] [1;4] (fun x y -> x > y) = true;;some2([0, 2], [1, 0, 3], (>)) == true;
some2([], [1], (x, y) => x > y) == false;
some2([2, 3], [1, 4], (x, y) => x > y) == true;val cmpByLength : 'a t -> 'a t -> intlet cmpByLength: t('a) => t('a) => int;cmpByLength l1 l2
Compare two lists solely by length. Returns -1 if length l1 is less than length l2, 0 if length l1 equals length l2, and 1 if length l1 is greater than length l2.
cmpByLength [1;2] [3;4;5;6] = -1;;
cmpByLength [1;2;3] [4;5;6] = 0;;
cmpByLength [1;2;3;4] [5;6] = 1;;cmpByLength([1, 2], [3, 4, 5, 6]) == (-1);
cmpByLength([1, 2, 3], [4, 5, 6]) == 0;
cmpByLength([1, 2, 3, 4], [5, 6]) == 1;val cmpU : 'a t -> 'a t -> ('a -> 'a -> int) Js.Fn.arity2 -> intlet cmpU: t('a) => t('a) => Js.Fn.arity2(('a => 'a => int)) => int;val cmp : 'a t -> 'a t -> ('a -> 'a -> int) -> intlet cmp: t('a) => t('a) => ('a => 'a => int) => int;Compare elements one by one f x y. f returns
- a negative number if
xis “less than”y - zero if
xis “equal to”y - a positive number if
xis “greater than”yThe comparison returns the first non-zero result off, or zero iffreturns zero for allxandy. If all items have compared equal, butxsis exhausted first, return -1. (xsis shorter) If all items have compared equal, butysis exhausted first, return 1 (xsis longer)
cmp [3] [3;7] (fun a b -> compare a b) = -1
cmp [5;3] [5] (fun a b -> compare a b) = 1
cmp [|1; 3; 5|] [|1; 4; 2|] (fun a b -> compare a b) = -1;;
cmp [|1; 3; 5|] [|1; 2; 3|] (fun a b -> compare a b) = 1;;
cmp [|1; 3; 5|] [|1; 3; 5|] (fun a b -> compare a b) = 0;;cmp([3], [3, 7], (a, b) => compare(a, b))
== - 1(cmp, [5, 3], [5], (a, b) => compare(a, b))
== 1(cmp, [|1, 3, 5|], [|1, 4, 2|], (a, b) => compare(a, b))
== (-1);
cmp([|1, 3, 5|], [|1, 2, 3|], (a, b) => compare(a, b)) == 1;
cmp([|1, 3, 5|], [|1, 3, 5|], (a, b) => compare(a, b)) == 0;Attention: The total ordering of List is different from Array, for Array, we compare the length first and, only if the lengths are equal, elements one by one. For lists, we just compare elements one by one
val eqU : 'a t -> 'a t -> ('a -> 'a -> bool) Js.Fn.arity2 -> boollet eqU: t('a) => t('a) => Js.Fn.arity2(('a => 'a => bool)) => bool;val eq : 'a t -> 'a t -> ('a -> 'a -> bool) -> boollet eq: t('a) => t('a) => ('a => 'a => bool) => bool;eq xs ys eqElem check equality of xs and ys using eqElem for equality on elements, where eqElem is a function that returns true if items x and y meet some criterion for equality, false otherwise. eq false if length of xs and ys are not the same.
eq [1;2;3] [1;2] (=) = false ;;
eq [1;2] [1;2] (=) = true;;
eq [1; 2; 3] [-1; -2; -3] (fun a b -> abs a = abs b) = true;;eq([1, 2, 3], [1, 2], (==)) == false;
eq([1, 2], [1, 2], (==)) == true;
eq([1, 2, 3], [(-1), (-2), (-3)], (a, b) => abs(a) == abs(b)) == true;val hasU : 'a t -> 'b -> ('a -> 'b -> bool) Js.Fn.arity2 -> boollet hasU: t('a) => 'b => Js.Fn.arity2(('a => 'b => bool)) => bool;val has : 'a t -> 'b -> ('a -> 'b -> bool) -> boollet has: t('a) => 'b => ('a => 'b => bool) => bool;has xs eqFcn returns true if the list contains at least one element for which eqFcn x returns true
has [1;2;3] 2 (=) = true;;
has [1;2;3] 4 (=) = false;;
has [-1;-2;-3] 2 (fun a b -> abs a = abs b) = true;;has([1, 2, 3], 2, (==)) == true;
has([1, 2, 3], 4, (==)) == false;
has([(-1), (-2), (-3)], 2, (a, b) => abs(a) == abs(b)) == true;val getByU : 'a t -> ('a -> bool) Js.Fn.arity1 -> 'a optionlet getByU: t('a) => Js.Fn.arity1(('a => bool)) => option('a);val getBy : 'a t -> ('a -> bool) -> 'a optionlet getBy: t('a) => ('a => bool) => option('a);getBy xs p returns Some value for the first value in xs that satisifies the predicate function p; returns None if no element satisifies the function.
getBy [1;4;3;2] (fun x -> x mod 2 = 0) = Some 4
getBy [15;13;11] (fun x -> x mod 2 = 0) = Noneval keepU : 'a t -> ('a -> bool) Js.Fn.arity1 -> 'a tlet keepU: t('a) => Js.Fn.arity1(('a => bool)) => t('a);val keep : 'a t -> ('a -> bool) -> 'a tlet keep: t('a) => ('a => bool) => t('a);keep xs p returns a list of all elements in xs which satisfy the predicate function p
keep [1;2;3;4] (fun x -> x mod 2 = 0) =
[2;4]keep([1, 2, 3, 4], x => x mod 2 == 0) == [2, 4];val keepWithIndexU : 'a t -> ('a -> int -> bool) Js.Fn.arity2 -> 'a tlet keepWithIndexU: t('a) => Js.Fn.arity2(('a => int => bool)) => t('a);val keepWithIndex : 'a t -> ('a -> int -> bool) -> 'a tlet keepWithIndex: t('a) => ('a => int => bool) => t('a);keepWithIndex xs p returns a list of all elements in xs which satisfy the predicate function p
keepWithIndex [1;2;3;4] (fun _x i -> i mod 2 = 0)
=
[1;3]keepWithIndex([1, 2, 3, 4], (_x, i) => i mod 2 == 0) == [1, 3];val keepMapU : 'a t -> ('a -> 'b option) Js.Fn.arity1 -> 'b tlet keepMapU: t('a) => Js.Fn.arity1(('a => option('b))) => t('b);val keepMap : 'a t -> ('a -> 'b option) -> 'b tlet keepMap: t('a) => ('a => option('b)) => t('b);keepMap xs f applies f to each element of xs. If f xi returns Some value, then value is kept in the resulting list; if f xi returns None, the element is not retained in the result.
keepMap [1;2;3;4] (fun x -> if x mod 2 = 0 then Some (-x ) else None)
=
[-2;-4]keepMap([1, 2, 3, 4], x =>
if (x mod 2 == 0) {
Some(- x);
} else {
None;
}
)
== [(-2), (-4)];val partitionU : 'a t -> ('a -> bool) Js.Fn.arity1 -> 'a t * 'a tlet partitionU: t('a) => Js.Fn.arity1(('a => bool)) => (t('a), t('a));val partition : 'a t -> ('a -> bool) -> 'a t * 'a tlet partition: t('a) => ('a => bool) => (t('a), t('a));partition xs p creates a pair of lists; the first list consists of all elements of xs that satisfy the predicate function p; the second list consists of all elements of xs that do not satisfy p
partition [1;2;3;4] (fun x -> x mod 2 = 0) =
([2;4], [1;3])partition([1, 2, 3, 4], x => x mod 2 == 0) == ([2, 4], [1, 3]);val unzip : ('a * 'b) t -> 'a t * 'b tlet unzip: t(('a, 'b)) => (t('a), t('b));unzip xs takes a list of pairs and creates a pair of lists. The first list contains all the first items of the pairs; the second list contains all the second items.
unzip [(1,2) ; (3,4)] = ([1;3], [2;4]);;
unzip [(1,2) ; (3,4) ; (5,6) ; (7,8)] = ([1;3;5;7], [2;4;6;8]);;unzip([(1, 2), (3, 4)]) == ([1, 3], [2, 4]);
unzip([(1, 2), (3, 4), (5, 6), (7, 8)]) == ([1, 3, 5, 7], [2, 4, 6, 8]);val getAssocU :
('a * 'c) t ->
'b ->
('a -> 'b -> bool) Js.Fn.arity2 ->
'c optionlet getAssocU:
t(('a, 'c)) =>
'b =>
Js.Fn.arity2(('a => 'b => bool)) =>
option('c);val getAssoc : ('a * 'c) t -> 'b -> ('a -> 'b -> bool) -> 'c optionlet getAssoc: t(('a, 'c)) => 'b => ('a => 'b => bool) => option('c);getAssoc xs k eq
return the second element of a pair in xs where the first element equals x as per the predicate function eq, or None if not found
getAssoc [ 1, "a"; 2, "b"; 3, "c"] 2 (=) = Some "b"
getAssoc [9, "morning"; 15, "afternoon"; 22, "night"] 3 (fun a b -> a mod 12 = b mod 12) = Some "afternoon"val hasAssocU : ('a * 'c) t -> 'b -> ('a -> 'b -> bool) Js.Fn.arity2 -> boollet hasAssocU: t(('a, 'c)) => 'b => Js.Fn.arity2(('a => 'b => bool)) => bool;val hasAssoc : ('a * 'c) t -> 'b -> ('a -> 'b -> bool) -> boollet hasAssoc: t(('a, 'c)) => 'b => ('a => 'b => bool) => bool;hasAssoc xs k eq return true if there is a pair in xs where the first element equals k as per the predicate funtion eq
hasAssoc [1, "a"; 2, "b"; 3,"c"] 1 (=) = true;;
hasAssoc [9, "morning"; 15, "afternoon"; 22, "night"] 3 (fun a b -> a mod 12 = b mod 12) = true;;hasAssoc([(1, "a"), (2, "b"), (3, "c")], 1, (==)) == true;
hasAssoc([(9, "morning"), (15, "afternoon"), (22, "night")], 3, (a, b) =>
a mod 12 == b mod 12
)
== true;val removeAssocU :
('a * 'c) t ->
'b ->
('a -> 'b -> bool) Js.Fn.arity2 ->
('a * 'c) tlet removeAssocU:
t(('a, 'c)) =>
'b =>
Js.Fn.arity2(('a => 'b => bool)) =>
t(('a, 'c));val removeAssoc : ('a * 'c) t -> 'b -> ('a -> 'b -> bool) -> ('a * 'c) tlet removeAssoc: t(('a, 'c)) => 'b => ('a => 'b => bool) => t(('a, 'c));removeAssoc xs k eq Return a list after removing the first pair whose first value is k per the equality predicate eq; if not found, return a new list identical to xs.
removeAssoc [1,"a"; 2, "b"; 3, "c" ] 1 (=) =
[2, "b"; 3, "c"]
removeAssoc [1,"a"; 2, "b"; 3, "c" ] 99 (=) =
[1, "a"; 2, "b"; 3, "c"]removeAssoc([(1, "a"), (2, "b"), (3, "c")], 1, (==))
== [(2, "b"), (3, "c")](
removeAssoc,
[(1, "a"), (2, "b"), (3, "c")],
99,
(==),
)
== [(1, "a"), (2, "b"), (3, "c")];val setAssocU :
('a * 'c) t ->
'a ->
'c ->
('a -> 'a -> bool) Js.Fn.arity2 ->
('a * 'c) tlet setAssocU:
t(('a, 'c)) =>
'a =>
'c =>
Js.Fn.arity2(('a => 'a => bool)) =>
t(('a, 'c));val setAssoc : ('a * 'c) t -> 'a -> 'c -> ('a -> 'a -> bool) -> ('a * 'c) tlet setAssoc: t(('a, 'c)) => 'a => 'c => ('a => 'a => bool) => t(('a, 'c));setAssoc xs k v eq if k exists in xs by satisfying the eq predicate, return a new list with the key and value replaced by the new k and v; otherwise, return a new list with the pair k, v added to the head of xs.
setAssoc [1,"a"; 2, "b"; 3, "c"] 2 "x" (=) =
[1,"a"; 2, "x"; 3,"c"] ;;
setAssoc [1,"a"; 3, "c"] 2 "b" (=) =
[2,"b"; 1,"a"; 3, "c"]
setAssoc [9, "morning"; 3, "morning?!"; 22, "night"] 15 "afternoon"
(fun a b -> a mod 12 = b mod 12) = [9, "morning"; 15, "afternoon"; 22, "night"]setAssoc([(1, "a"), (2, "b"), (3, "c")], 2, "x", (==))
== [(1, "a"), (2, "x"), (3, "c")];
setAssoc([(1, "a"), (3, "c")], 2, "b", (==))
== [(2, "b"), (1, "a"), (3, "c")](
setAssoc,
[(9, "morning"), (3, "morning?!"), (22, "night")],
15,
"afternoon",
(a, b) =>
a mod 12 == b mod 12
)
== [(9, "morning"), (15, "afternoon"), (22, "night")];Note carefully the last example! Since 15 mod 12 equals 3 mod 12, both the key and value are replaced in the list.
val sortU : 'a t -> ('a -> 'a -> int) Js.Fn.arity2 -> 'a tlet sortU: t('a) => Js.Fn.arity2(('a => 'a => int)) => t('a);val sort : 'a t -> ('a -> 'a -> int) -> 'a tlet sort: t('a) => ('a => 'a => int) => t('a);sort xs Returns a sorted list.
sort [5; 4; 9; 3; 7] (fun a b -> a - b) = [3; 4; 5; 7; 9]sort([5, 4, 9, 3, 7], (a, b) => a - b) == [3, 4, 5, 7, 9];