Module
pooka/list
src/pooka/list.pookaA list is a patient little queue; its old versions keep their places.
Build and transform immutable singly linked lists. Functions take the list first so a chain of transformations can travel through pipes. Indexes start at zero; ranges exclude their upper bound. Sorting is stable, and callbacks run in list order.
import pooka/list
assert ([1, 2, 3] |> list.map(fn(x) { x * 2 })) == [2, 4, 6]
API reference
- functionempty
- functionis_empty
- functionlength
- functionfirst
- functionlast
- functionat
- functionprepend
- functionappend
- functionconcat
- functionreverse
- functionmap
- functionfilter
- functionfilter_map
- functionfold
- functionfind
- functionany
- functionall
- functioncontains
- functiontake
- functiondrop
- functionsort
- functionsort_by
- functionunique
- functionrange
empty() -> List(a)
fn() -> List(a)Return an empty list, ready to welcome elements of one inferred type.
import pooka/list
assert list.empty() == []
is_empty(values: List(a)) -> Bool
fn(List(a)) -> BoolAsk whether the list has no elements.
import pooka/list
assert list.is_empty([])
length(values: List(a)) -> Int
fn(List(a)) -> IntCount elements from left to right; this walks the list.
import pooka/list
assert list.length([1, 2, 3]) == 3
first(values: List(a)) -> Option(a)
fn(List(a)) -> Option(a)Open the first envelope, or return None for an empty list.
import pooka/list
assert list.first([4, 5]) == Some(4)
last(values: List(a)) -> Option(a)
fn(List(a)) -> Option(a)Walk to the final element, or return None when there is none.
import pooka/list
assert list.last([4, 5]) == Some(5)
at(values: List(a), index: Int) -> Option(a)
fn(List(a), Int) -> Option(a)Read a zero-based index. Negative and out-of-range indexes return None.
import pooka/list
assert list.at([4, 5], 1) == Some(5)
prepend(values: List(a), value: a) -> List(a)
fn(List(a), a) -> List(a)Put a value at the front without walking the existing list.
import pooka/list
assert list.prepend([2, 3], 1) == [1, 2, 3]
append(values: List(a), value: a) -> List(a)
fn(List(a), a) -> List(a)Put a value at the end, rebuilding the path through the original list.
import pooka/list
assert list.append([1, 2], 3) == [1, 2, 3]
concat(left: List(a), right: List(a)) -> List(a)
fn(List(a), List(a)) -> List(a)Join two lists while retaining their element order.
import pooka/list
assert list.concat([1, 2], [3]) == [1, 2, 3]
reverse(values: List(a)) -> List(a)
fn(List(a)) -> List(a)Turn the list around using a tail-recursive fold.
import pooka/list
assert list.reverse([1, 2, 3]) == [3, 2, 1]
map(values: List(a), transform: fn(a) -> b) -> List(b)
fn(List(a), fn(a) -> b) -> List(b)Visit each element once and keep the callback results in their original order.
import pooka/list
assert list.map([1, 2], fn(x) { x * 2 }) == [2, 4]
filter(values: List(a), keep: fn(a) -> Bool) -> List(a)
fn(List(a), fn(a) -> Bool) -> List(a)Keep the elements whose predicate returns True, preserving their order.
import pooka/list
assert list.filter([1, 2, 3], fn(x) { x > 1 }) == [2, 3]
filter_map(values: List(a), transform: fn(a) -> Option(b)) -> List(b)
fn(List(a), fn(a) -> Option(b)) -> List(b)Let each callback either send a transformed value onward or quietly return None.
import pooka/list
assert list.filter_map([1, 2], fn(x) { Some(x + 1) }) == [2, 3]
fold(values: List(a), initial: b, step: fn(b, a) -> b) -> b
fn(List(a), b, fn(b, a) -> b) -> bCarry an accumulator through the list. The callback receives accumulator first, element second.
import pooka/list
assert list.fold([1, 2, 3], 0, fn(acc, x) { acc + x }) == 6
find(values: List(a), predicate: fn(a) -> Bool) -> Option(a)
fn(List(a), fn(a) -> Bool) -> Option(a)Stop at the first element accepted by the predicate.
import pooka/list
assert list.find([1, 2, 3], fn(x) { x > 1 }) == Some(2)
any(values: List(a), predicate: fn(a) -> Bool) -> Bool
fn(List(a), fn(a) -> Bool) -> BoolReturn True as soon as one element satisfies the predicate.
import pooka/list
assert list.any([1, 2], fn(x) { x == 2 })
all(values: List(a), predicate: fn(a) -> Bool) -> Bool
fn(List(a), fn(a) -> Bool) -> BoolRequire every element to satisfy the predicate. The empty list has no counterexample.
import pooka/list
assert list.all([], fn(x: Int) { x > 0 })
contains(values: List(a), value: a) -> Bool
fn(List(a), a) -> BoolTest membership with the language's equality operation.
import pooka/list
assert list.contains([1, 2], 2)
take(values: List(a), count: Int) -> List(a)
fn(List(a), Int) -> List(a)Keep at most count elements. A nonpositive count produces an empty list.
import pooka/list
assert list.take([1, 2, 3], 2) == [1, 2]
drop(values: List(a), count: Int) -> List(a)
fn(List(a), Int) -> List(a)Discard at most count elements. A nonpositive count leaves the list alone.
import pooka/list
assert list.drop([1, 2, 3], 2) == [3]
sort(values: List(a)) -> List(a)
fn(List(a)) -> List(a)Stable-sort using the Erlang term order exposed by the comparison primitive.
import pooka/list
assert list.sort([3, 1, 2]) == [1, 2, 3]
sort_by(values: List(a), compare: fn(a, a) -> Order) -> List(a)
fn(List(a), fn(a, a) -> pooka/order.Order) -> List(a)Stable-sort using a callback returning Order; equal elements retain their relative order.
import pooka/list
import pooka/order.{Order}
assert list.sort_by([3, 1, 2], fn(a, b) { order.from_int(a - b) }) == [1, 2, 3]
unique(values: List(a)) -> List(a)
fn(List(a)) -> List(a)Keep the first occurrence of each value. Equality is checked against values already kept.
import pooka/list
assert list.unique([2, 1, 2, 1]) == [2, 1]
range(start: Int, end: Int) -> List(Int)
fn(Int, Int) -> List(Int)Count upward from start, stopping before end. Reversed or empty bounds produce an empty list.
import pooka/list
assert list.range(2, 5) == [2, 3, 4]