Remove duplicate elements, preserving first occurrence, using a custom equality. $$\text{nubBy}(eq, [x_1, \ldots, x_n])$$ keeps $x_i$ if no earlier $x_j$ satisfies $\text{eq}(x_j, x_i)$.
Equations
- Data.List'.nubBy eq l = Data.List'.nubBy.go eq l []
Instances For
Equations
- Data.List'.nubBy.go eq [] a✝ = a✝.reverse
- Data.List'.nubBy.go eq (x_2 :: xs) a✝ = if a✝.any (eq x_2) = true then Data.List'.nubBy.go eq xs a✝ else Data.List'.nubBy.go eq xs (x_2 :: a✝)
Instances For
Remove duplicate elements using BEq, preserving first occurrence.
$$\text{nub} = \text{nubBy}(\text{BEq.beq})$$
Equations
- Data.List'.nub l = Data.List'.nubBy (fun (x1 x2 : α) => x1 == x2) l
Instances For
Group consecutive equal elements by a custom equality. $$\text{groupBy}(eq, [a, a, b, b, b, a]) = [[a, a], [b, b, b], [a]]$$
Equations
- Data.List'.groupBy eq [] = []
- Data.List'.groupBy eq (x_1 :: xs) = (x_1 :: List.takeWhile (eq x_1) xs) :: Data.List'.groupBy eq (List.drop (List.takeWhile (eq x_1) xs).length xs)
Instances For
Group consecutive equal elements using BEq.
$$\text{group} = \text{groupBy}(\text{BEq.beq})$$
Equations
- Data.List'.group l = Data.List'.groupBy (fun (x1 x2 : α) => x1 == x2) l
Instances For
Transpose a list of lists (rows to columns). $$\text{transpose}([[1,2,3],[4,5,6]]) = [[1,4],[2,5],[3,6]]$$ Uses fuel-based termination.
Equations
- Data.List'.transpose xss = Data.List'.transpose.go xss (List.foldl (fun (acc : Nat) (l : List α) => max acc l.length) 0 xss)
Instances For
All suffixes, from longest to shortest, including [].
Returns NonEmpty since every list has at least the empty suffix.
$$\text{tails}([1,2,3]) = [[1,2,3],[2,3],[3],[]]$$
Equations
- Data.List'.tails [] = Data.List.NonEmpty.singleton []
- Data.List'.tails (x_1 :: xs) = { head := x_1 :: xs, tail := (Data.List'.tails xs).toList }
Instances For
All prefixes, from shortest to longest.
Returns NonEmpty since every list has at least the empty prefix.
$$\text{inits}([1,2,3]) = [[],[1],[1,2],[1,2,3]]$$
Equations
- Data.List'.inits [] = Data.List.NonEmpty.singleton []
- Data.List'.inits (x_1 :: xs) = { head := [], tail := List.map (fun (x : List α) => x_1 :: x) (Data.List'.inits xs).toList }
Instances For
All subsequences (power set), including [].
$$|\text{subsequences}(l)| = 2^{|l|}$$
Equations
- Data.List'.subsequences [] = [[]]
- Data.List'.subsequences (x_1 :: xs) = Data.List'.subsequences xs ++ List.map (fun (x : List α) => x_1 :: x) (Data.List'.subsequences xs)
Instances For
All permutations of a list. $$|\text{permutations}(l)| = |l|!$$
Equations
Instances For
Build a list from a seed by repeatedly applying f.
$$\text{unfoldr}(f, b_0) = [a_1, a_2, \ldots]$$
where $f(b_i) = \text{some}(a_{i+1}, b_{i+1})$ until $f(b_n) = \text{none}$.
Fuel-limited to ensure termination.
Equations
Instances For
Right-to-left scan, producing all intermediate accumulators.
Returns NonEmpty since the result always includes at least the initial accumulator z.
$$\text{scanr}(f, z, [x_1, \ldots, x_n]) = [f(x_1, f(x_2, \ldots f(x_n, z))), \ldots, f(x_n, z), z]$$
Equations
- Data.List'.scanr f z [] = Data.List.NonEmpty.singleton z
- Data.List'.scanr f z (x_1 :: xs) = { head := f x_1 (Data.List'.scanr f z xs).head, tail := (Data.List'.scanr f z xs).toList }
Instances For
Left-to-right map with accumulator. $$\text{mapAccumL}(f, s_0, [x_1, \ldots, x_n]) = (s_n, [y_1, \ldots, y_n])$$ where $(s_i, y_i) = f(s_{i-1}, x_i)$.
Equations
Instances For
Right-to-left map with accumulator. $$\text{mapAccumR}(f, s_0, [x_1, \ldots, x_n]) = (s_n, [y_1, \ldots, y_n])$$ where processing goes right-to-left.
Equations
Instances For
Intercalate: insert a separator between lists and flatten. $$\text{intercalate}(sep, [l_1, \ldots, l_n]) = l_1 \mathbin{++} sep \mathbin{++} l_2 \mathbin{++} \cdots \mathbin{++} l_n$$
Equations
- Data.List'.intercalate sep [] = []
- Data.List'.intercalate sep [x_1] = x_1
- Data.List'.intercalate sep (x_1 :: xs) = x_1 ++ sep ++ Data.List'.intercalate sep xs
Instances For
Sort by a derived key. $$\text{sortOn}(f, l)$$ sorts $l$ by comparing $f(x)$ values.
Equations
- Data.List'.sortOn f l = (l.toArray.qsort fun (a b : α) => compare (f a) (f b) == Ordering.lt).toList
Instances For
Maximum element by a custom comparator, or none for empty lists.
$$\text{maximumBy}(\text{cmp}, l)$$
Equations
- Data.List'.maximumBy cmp [] = none
- Data.List'.maximumBy cmp (x_1 :: xs) = some (List.foldl (fun (acc y : α) => if (cmp acc y == Ordering.lt) = true then y else acc) x_1 xs)
Instances For
Minimum element by a custom comparator, or none for empty lists.
$$\text{minimumBy}(\text{cmp}, l)$$
Equations
- Data.List'.minimumBy cmp [] = none
- Data.List'.minimumBy cmp (x_1 :: xs) = some (List.foldl (fun (acc y : α) => if (cmp acc y == Ordering.gt) = true then y else acc) x_1 xs)
Instances For
Delete the first occurrence matching the predicate. $$\text{deleteBy}(eq, x, l)$$ removes the first $y$ in $l$ with $\text{eq}(x, y)$.
Equations
Instances For
List union by a custom equality. $$\text{unionBy}(eq, l_1, l_2)$$ appends elements of $l_2$ not in $l_1$.
Equations
- Data.List'.unionBy eq xs ys = xs ++ List.filter (fun (y : α) => !xs.any (eq y)) ys
Instances For
List intersection by a custom equality. $$\text{intersectBy}(eq, l_1, l_2)$$ keeps elements of $l_1$ that are in $l_2$.
Equations
- Data.List'.intersectBy eq xs ys = List.filter (fun (x : α) => ys.any (eq x)) xs
Instances For
Insert into a sorted list, maintaining order. $$\text{insertBy}(\text{cmp}, x, l)$$ places $x$ before the first element greater than it.
Equations
- Data.List'.insertBy cmp x [] = [x]
- Data.List'.insertBy cmp x (x_2 :: xs) = if (cmp x x_2 != Ordering.gt) = true then x :: x_2 :: xs else x_2 :: Data.List'.insertBy cmp x xs
Instances For
genericLength is List.length in Lean (which already returns Nat).
$$\text{genericLength}(l) = |l|$$