Module List

Finite list types and list combinators.

let xs = *(1, 2, 3)
xs->List.Map(box [n] n * 2)
type List<a> = recursive either {
  .end!,
  .item(a) self,
}

A finite, ordered sequence of values.

*(1, 2, 3)  // syntax sugar for .item(1) .item(2) .item(3) .end!
type List.Builder<a> = iterative choice {
  .add(a) => self,
  .build* => List<a>,
}

Incrementally constructs a list.

dec List.All : [<a: drop> List<a>, box [a] Bool] Bool

Returns .true! if the test function holds for all elements. Short-circuits on the first .false!.

dec List.Any : [<a: drop> List<a>, box [a] Bool] Bool

Returns .true! if the test function holds for at least one element. Short-circuits on the first .true!.

dec List.Concat : [<a> List<List<a>>] List<a>

Flattens a list of lists into a single list.

dec List.Copy : [<a> dual List<a>, List<a>] dual List<a>

Yields all items from a source list onto a destination channel, consuming the source.

dec List.Drop : [<a: drop> List<a>, Nat] List<a>

Drops the requested number of elements from the start of a list.

dec List.DropWhile : [<a: share> List<a>, box [a] Bool] List<a>

Drops elements from the start while the test function returns .true!.

dec List.Filter : [<a: share> List<a>, box [a] Bool] List<a>

Keeps the elements for which the test function returns .true!.

dec List.FilterMap : [<a> List<a>, <b> box [a] Option<b>] List<b>

Maps each element to an optional value, keeping only the present results.

dec List.Find : [<a: share> List<a>, box [a] Bool] Option<a>

Returns the first element for which the test function returns .true!.

dec List.FlatMap : [<a> List<a>, <b> box [a] List<b>] List<b>

Maps each element to a list, then concatenates the result.

dec List.ForEach : [<r> r, <a> List<a>, box [r, a] r] r

Applies a folding function repeatedly to the current result and each list element, returning the final result.

Expression syntax:

0->List.ForEach(*(1, 2, 3), box [sum, n] sum + n)
// = 6

Process syntax:

let console = Console.Open
console->List.ForEach(Nat.Range(1, 10), box [c, i]
  c.print(`#{i}`)
)
console.close
dec List.Length : [<a: drop> List<a>] Nat

Returns the number of elements in a list.

dec List.Map : [<a> List<a>, <b> box [a] b] List<b>

Applies a mapping function to each element of a list.

*(1, 2, 3)->List.Map(box [n] n * 2)
// = *(2, 4, 6)
dec List.Max : [<a: data> List<a>] Option<a>

Returns the largest element, or .none! for an empty list.

dec List.Merge : [<a> List<List<a>>] List<a>

Nondeterministically merges lists into a single list. The order of elements is determined by readiness. Items of a single list are yielded in order, but items from different lists may be interleaved depending on which list is ready to yield next.

This is an implementation of a fan-in pattern, where a single consumer receives items from multiple producers.

dec List.Min : [<a: data> List<a>] Option<a>

Returns the smallest element, or .none! for an empty list.

dec List.Reverse : [<a> List<a>] List<a>

Returns a list with the elements in reverse order.

dec List.Sort : [<a: data> List<a>] List<a>

Sorts a list in ascending data order. Equal keys keep their original order.

dec List.SortBy : [<a: share> List<a>, <k: data> box [a] k] List<a>

Sorts a non-linear list by an extracted data key.

dec List.SortDesc : [<a: data> List<a>] List<a>

Sorts a list in descending data order. Equal keys keep their original order.

dec List.SortDescBy : [<a: share> List<a>, <k: data> box [a] k] List<a>

Sorts a non-linear list by an extracted data key in descending order.

dec List.SortLinearBy : [<a> List<a>, <k: data> box [a] (k) a] List<a>

Sorts a linear list by a function that returns both the key and the item.

dec List.SortLinearDescBy : [<a> List<a>, <k: data> box [a] (k) a] List<a>

Sorts a linear list by a key in descending order.

dec List.Sum : [<a: number> List<a>] a

Calculates the sum of all elements in a list.

dec List.Take : [<a: drop> List<a>, Nat] List<a>

Returns up to the requested number of elements from the start of a list.

dec List.TakeWhile : [<a: share> List<a>, box [a] Bool] List<a>

Takes elements from the start while the test function returns .true!.

dec List.Unzip : [<a, b> List<(a) b>] (List<a>) List<b>

Splits a list of pairs into a pair of lists.

dec List.Zip : [<a: drop> List<a>, <b: drop> List<b>] List<(a) b>

Zips two lists into a list of pairs. Stops at the shorter list.