Eager, persistent, singly-linked lists.

All operations are recursive over cons cells; mutation is not possible. Helpers come in five flavours: queries, access, construction, transformations, and search. Everything is polymorphic in the element type T.

Examples

use Std.List

let xs = [1, 2, 3, 4, 5]
length(xs)                                # => 5
map(xs, fn(x) -> x * x)                   # => [1, 4, 9, 16, 25]
filter(xs, fn(x) -> x % 2 == 0)           # => [2, 4]
use Std.List

# Sum of squares of positive integers up to 10
let r = range_list(1, 11)                 # [1..10]
          |> filter(fn(x) -> x > 0)
          |> map(fn(x) -> x * x)
          |> sum
# r => 385
use Std.List

match uncons([1, 2, 3])
  %[h, t] -> Std.Io.print_int(h)          # prints 1
  _       -> Std.Io.println("empty")

Functions

  • # fn __group__() -> Atom

    Group tag consumed by Cure.Stdlib.Preload.

  • # fn all(list: List(T), pred: (T) -> Bool) -> Bool

    true when every element satisfies pred (vacuously true for []).

  • # fn any(list: List(T), pred: (T) -> Bool) -> Bool

    true when at least one element satisfies pred.

  • # fn append(a: List(T), b: List(T)) -> List(T)

    Concatenate two lists. Linear in length(a).

  • # fn concat(lists: List(List(T))) -> List(T)

    Concatenate a list of lists into a single flat list.

  • # fn cons(elem: T, list: List(T)) -> List(T)

    Prepend elem onto list (the Cure-level spelling of [elem | list]).

  • # fn contains(list: List(T), elem: T) -> Bool

    true when elem appears in list (structural equality).

  • # fn count(list: List(T), pred: (T) -> Bool) -> Int

    Count of elements satisfying pred.

  • # fn drop(list: List(T), n: Int) -> List(T)

    Drop the first n elements; returns list unchanged when n <= 0.

  • # fn filter(list: List(T), pred: (T) -> Bool) -> List(T)

    Keep elements of list for which pred(elem) returns true.

  • # fn find(list: List(T), pred: (T) -> Bool, default: T) -> T

    First element satisfying pred; returns default when nothing matches.

  • # fn flat_map(list: List(T), f: (T) -> List(U)) -> List(U)

    Map f over list and flatten one level of nesting.

  • # fn foldl(list: List(T), acc: U, f: (T) -> (U) -> U) -> U

    Left fold. f is curried: f(elem)(acc) -> acc. Reduces list starting from the head.

  • # fn foldr(list: List(T), acc: U, f: (T) -> (U) -> U) -> U

    Right fold. f is curried: f(elem)(acc) -> acc. Builds up the result from the tail toward the head; not tail-recursive, so expect O(length) stack on very long lists.

  • # fn head(list: List(T), default: T) -> T

    First element of list; returns default when empty.

  • # fn is_empty(list: List(T)) -> Bool

    true when list has no elements.

  • # fn last(list: List(T), default: T) -> T

    Last element of list; returns default when empty.

  • # fn length(list: List(T)) -> Int extern

    Length of list as an Int. Delegates to :erlang.length/1.

  • # fn map(list: List(T), f: (T) -> U) -> List(U)

    Map f over every element of list.

  • # fn nth(list: List(T), idx: Int, default: T) -> T

    0-based random access. Returns default when idx is out of range.

  • # fn product(list: List(Int)) -> Int

    Product of an Int list, left-folded.

  • # fn reverse(list: List(T)) -> List(T)

    Reverse list; tail-recursive via a private accumulator.

  • # fn split_first(list: List(T), default: T) -> Tuple

    Like uncons/1, but substitutes default for the head when empty.

  • # fn sum(list: List(Int)) -> Int

    Sum of an Int list, left-folded.

  • # fn tail(list: List(T)) -> List(T)

    All-but-the-first elements of list; empty list yields [].

  • # fn take(list: List(T), n: Int) -> List(T)

    First n elements; [] when n <= 0.

  • # fn uncons(list: List(T)) -> Tuple

    Split list into %[head, tail]; empty list maps to %[[], []].

  • # fn zip_with(a: List(T), b: List(U), f: (T) -> (U) -> V) -> List(V)

    Combine two lists element-wise using f. Stops at the shorter list. f is curried: f(a)(b) -> c.