list.h

Cons-lists.

Defines

ML99_cons(x, xs)

Prepends x to xs.

Examples

#include <metalang99/list.h>

ML99_cons(v(1), ML99_cons(v(2), ML99_nil()))
ML99_nil(...)

The empty list.

ML99_isCons(list)

Checks list for non-emptiness.

Examples

#include <metalang99/list.h>

// 1
ML99_isCons(ML99_list(v(1, 2, 3)))

// 0
ML99_isCons(ML99_nil())
ML99_isNil(list)

Checks list for emptiness.

Examples

#include <metalang99/list.h>

// 0
ML99_isNil(ML99_list(v(1, 2, 3)))

// 1
ML99_isNil(ML99_nil())
ML99_listHead(list)

Extracts the head from the non-empty list list.

Examples

#include <metalang99/list.h>

// 1
ML99_listHead(ML99_list(v(1, 2, 3)))
ML99_listTail(list)

Extracts the tail from the non-empty list list.

Examples

#include <metalang99/list.h>

// 2, 3
ML99_listTail(ML99_list(v(1, 2, 3)))

// ML99_nil()
ML99_listTail(ML99_list(v(1)))
ML99_listLast(list)

Extracts the last element from the non-empty list list.

Examples

#include <metalang99/list.h>

// 3
ML99_listLast(ML99_list(v(1, 2, 3)))
ML99_listInit(list)

Extracts all the elements of the non-empty list list except the last one.

Examples

#include <metalang99/list.h>

// 1, 2
ML99_listInit(ML99_list(v(1, 2, 3)))

// ML99_nil()
ML99_listInit(ML99_list(v(1)))
ML99_list(...)

Constructs a list from its arguments.

At most 63 arguments are acceptable.

Examples

#include <metalang99/list.h>

// 1, 2, 3
ML99_list(v(1, 2, 3))
ML99_listFromTuples(f, ...)

Constructs a list from comma-separated tuples.

It sequentially applies f to each untupled argument, thus forming the resulting list. If some argument is not a tuple, a fatal error is emitted.

The result is ML99_list(ML99_appl(f, ML99_untuple(x1)), ..., ML99_appl(f, ML99_untuple(xN))).

Each variadic argument inherits all the preconditions of ML99_isUntuple.

Examples

#include <metalang99/list.h>

#define F_IMPL(x, y) v(x + y)
#define F_ARITY      1

// ML99_list(v(1 + 2, 3 + 4, 5 + 6))
ML99_listFromTuples(v(F), v((1, 2), (3, 4), (5, 6)))
ML99_listFromSeq(seq)

Constructs a list from the sequence seq.

Note that seq items must not contain commas. If you want commas in items, such as (+, -, *, /), consider wrapping an item in parentheses: ((+, -, *, /)).

Examples

#include <metalang99/list.h>

// ML99_nil()
ML99_listFromSeq(v())

// ML99_list(v(1, 2, 3))
ML99_listFromSeq(v((1)(2)(3)))
ML99_listLen(list)

Computes the length of list.

Examples

#include <metalang99/list.h>

// 0
ML99_listLen(ML99_nil())

// 3
ML99_listLen(ML99_list(v(1, 2, 3)))
ML99_LIST_EVAL(...)

Evaluates a metaprogram that reduces to a list, then unwraps it.

It behaves the same as the composition of ML99_EVAL and ML99_listUnwrap.

Examples

#include <metalang99/list.h>

// Literally 1 2 3
ML99_LIST_EVAL(ML99_list(v(1, 2, 3)))

Note

This macro does not result in a Metalang99 term; it literally pastes list elements into a source file.

ML99_LIST_EVAL_COMMA_SEP(...)

The same as ML99_LIST_EVAL but intersperses a comma between list items.

Examples

#include <metalang99/util.h>

// Literally 1, 2, 3
ML99_LIST_EVAL_COMMA_SEP(ML99_list(v(1, 2, 3)))

Note

This macro does not result in a Metalang99 term; it literally pastes comma-separated list elements into a source file.

ML99_listAppend(list, other)

Appends the list other to list.

Examples

#include <metalang99/list.h>

// 1, 2, 3
ML99_listAppend(ML99_list(v(1)), ML99_list(v(2, 3)))
ML99_listAppendItem(item, list)

Appends the item item to list.

Examples

#include <metalang99/list.h>

// 1, 2, 3
ML99_listAppendItem(v(3), ML99_list(v(1, 2)))
ML99_listUnwrap(list)

Places all the items in list as-is.

Examples

#include <metalang99/list.h>

// Literally 1 2 3
ML99_listUnwrap(ML99_list(v(1, 2, 3)))

See also

ML99_LIST_EVAL

Note

The resulting value is still a valid Metalang99 term that need to be evaluated further.

ML99_listUnwrapCommaSep(list)

Places all the items in list as-is, separated by commas.

Examples

#include <metalang99/list.h>

// Literally 1, 2, 3
ML99_listUnwrapCommaSep(ML99_list(v(1, 2, 3)))

See also

ML99_LIST_EVAL

Note

The resulting value is still a valid Metalang99 term that need to be evaluated further.

ML99_listReverse(list)

Reverses the order of items in list.

Examples

#include <metalang99/list.h>

// 3, 2, 1
ML99_listReverse(ML99_list(v(1, 2, 3)))
ML99_listGet(i, list)

Extracts the i -indexed element.

Examples

#include <metalang99/list.h>

// 2
ML99_listGet(v(1), ML99_list(v(1, 2, 3)))
ML99_listFoldr(f, init, list)

A right-associative fold over list.

Examples

#include <metalang99/list.h>

#define ABCDEFG 123

// 7
ML99_listFoldr(v(ML99_cat), v(7), ML99_nil())

// 123
ML99_listFoldr(ML99_appl(v(ML99_flip), v(ML99_cat)), v(A), ML99_list(v(G, DEF, BC)))
ML99_listFoldl(f, init, list)

A left-associative fold over list.

Examples

#include <metalang99/list.h>

#define ABCDEFG 123

// 7
ML99_listFoldl(v(ML99_cat), v(7), ML99_nil())

// 123
ML99_listFoldl(v(ML99_cat), v(A), ML99_list(v(BC, DEF, G)))
ML99_listFoldl1(f, list)

The same as ML99_listFoldl but treats the first element of list as the initial value.

Examples

#include <metalang99/list.h>

#define ABCDEFG 123

// 123
ML99_listFoldl1(v(ML99_cat), ML99_list(v(AB, CDEF, G)))
ML99_listIntersperse(item, list)

Intersperses item between the items in list.

Examples

#include <metalang99/list.h>

// 1, +, 2, +, 3
ML99_listIntersperse(v(+), ML99_list(v(1, 2, 3)))
ML99_listPrependToAll(item, list)

Prepends item to all items in list.

Examples

#include <metalang99/list.h>

// +, 1, +, 2, +, 3
ML99_listPrependToAll(v(+), ML99_list(v(1, 2, 3)))
ML99_listMap(f, list)

Maps all the elements in list with f.

Examples

#include <metalang99/list.h>
#include <metalang99/nat.h>

// 4, 5, 6
ML99_listMap(ML99_appl(v(ML99_add), v(3)), ML99_list(v(1, 2, 3)))
ML99_listMapI(f, list)

The same as ML99_listMap but provides an index of an element to f.

Examples

#include <metalang99/list.h>

#define F_IMPL(x, i) v(x[i])
#define F_ARITY      2

// a[0], b[1], c[2]
ML99_listMapI(v(F), ML99_list(v(a, b, c)))
ML99_listMapInPlace(f, list)

A more efficient version of ML99_listUnwrap(ML99_listMap(f, list)).

Note

Unlike ML99_listMap, f can evaluate to many terms.

ML99_listMapInPlaceI(f, list)

A more efficient version of ML99_listUnwrap(ML99_listMapI(f, list)).

Note

Unlike ML99_listMapI, f can evaluate to many terms.

ML99_listFor(list, f)

The same as ML99_listMap but with the reversed order of arguments.

Examples

#include <metalang99/list.h>
#include <metalang99/nat.h>

// 4, 5, 6
ML99_listFor(ML99_list(v(1, 2, 3)), ML99_appl(v(ML99_add), v(3)))
ML99_listMapInitLast(f_init, f_last, list)

Maps the initial elements of the non-empty list list with f_init and the last element with f_last.

Examples

// 4, 5, 10
ML99_listMapInitLast(ML99_appl(v(ML99_add), v(3)), ML99_appl(v(ML99_add), v(7)), ML99_list(v(1,
2, 3)))
ML99_listForInitLast(list, f_init, f_last)

The same as ML99_listMapInitLast but accepts list as the first parameter.

Examples

// 4, 5, 10
ML99_listForInitLast(ML99_list(v(1, 2, 3)), ML99_appl(v(ML99_add), v(3)), ML99_appl(v(ML99_add),
v(7)))
ML99_listFilter(f, list)

Filters list with f.

Examples

#include <metalang99/list.h>
#include <metalang99/nat.h>

// 9, 11, 6
ML99_listFilter(ML99_appl(v(ML99_lesser), v(5)), ML99_list(v(9, 1, 11, 6, 0, 4)))
ML99_listFilterMap(f, list)

A combination of ML99_listFilter and ML99_listMap.

It builds a new list by applying f to each element in list: if f yields ML99_just(x), x is passed to the new list, otherwise (ML99_nothing()), the value is neglected.

Examples

#include <metalang99/list.h>
#include <metalang99/maybe.h>

#define MAYBE_LIST ML99_list(ML99_just(v(5)), ML99_nothing(), ML99_just(v(7)))

// 5, 7
ML99_listFilterMap(v(ML99_id), MAYBE_LIST)
ML99_listEq(cmp, list, other)

Tests list and other for equality.

Examples

#include <metalang99/list.h>
#include <metalang99/nat.h>

// 0
ML99_listEq(v(ML99_natEq), ML99_list(v(1, 2, 3)), ML99_list(v(4, 5, 6)))

// 1
ML99_listEq(v(ML99_natEq), ML99_list(v(1, 2, 3)), ML99_list(v(1, 2, 3)))
ML99_listContains(cmp, item, list)

Checks whether item resides in list.

Examples

#include <metalang99/list.h>
#include <metalang99/nat.h>

// 1
ML99_listContains(v(ML99_natEq), v(3), ML99_list(v(1, 2, 3)))

// 0
ML99_listContains(v(ML99_natEq), v(456), ML99_list(v(1, 2, 3)))
ML99_listTake(n, list)

Extracts the prefix of list of the length n.

If n is greater than the length of list, the whole list is returned.

Examples

#include <metalang99/list.h>

// 1, 2
ML99_listTake(v(2), ML99_list(v(1, 2, 3)))
ML99_listTakeWhile(f, list)

Extracts the items from list as long as f evaluates to ML99_true().

Examples

#include <metalang99/list.h>
#include <metalang99/nat.h>

// 1, 2, 3
ML99_listTakeWhile(ML99_appl(v(ML99_greater), v(4)), ML99_list(v(1, 2, 3, 4, 5, 6)))
ML99_listDrop(n, list)

Removes the prefix of list of the length n.

If n is greater than the length of list, ML99_nil() is returned.

Examples

#include <metalang99/list.h>

// 2, 3
ML99_listDrop(v(1), ML99_list(v(1, 2, 3)))
ML99_listDropWhile(f, list)

Removes the items from list as long as f evaluates to ML99_true().

Examples

#include <metalang99/list.h>
#include <metalang99/nat.h>

// 4, 5, 6
ML99_listDropWhile(ML99_appl(v(ML99_lesser), v(4)), ML99_list(v(1, 2, 3, 4, 5, 6)))
ML99_listZip(list, other)

Computes a list of two-place tuples of the corresponding items from list and other.

Examples

#include <metalang99/list.h>

// (1, 4), (2, 5), (3, 6)
ML99_listZip(ML99_list(v(1, 2, 3)), ML99_list(v(4, 5, 6)))
ML99_listUnzip(list)

Transforms a list of two-place tuples into a tuple of a list of the first components and a list of the second components.

Examples

#include <metalang99/list.h>
#include <metalang99/tuple.h>

// ML99_tuple(ML99_list(v(1, 2, 3)), ML99_list(v(4, 5, 6)))
ML99_listUnzip(ML99_list(ML99_tuple(v(1, 4)), ML99_tuple(v(2, 5)), ML99_tuple(v(3, 6))))
ML99_listReplicate(n, item)

Computes a list of length n with each element item.

Examples

#include <metalang99/list.h>

// ~, ~, ~, ~, ~
ML99_listReplicate(v(5), v(~))

// ML99_nil()
ML99_listReplicate(v(0), v(~))
ML99_listPartition(f, list)

Returns a two-place tuple of lists: those items of list the do and do not satisfy the predicate f, respectively.

Examples

#include <metalang99/list.h>
#include <metalang99/nat.h>

// ML99_tuple(ML99_list(v(4, 7)), ML99_list(v(11, 12, 13)))
ML99_listPartition(ML99_appl(v(ML99_greater), v(10)), ML99_list(v(11, 4, 12, 13, 7)))
ML99_listAppl(f, list)

Applies all the items in list to f.

If the list is empty, results in f as-is.

Examples

#include <metalang99/list.h>
#include <metalang99/nat.h>

// ML99_add
ML99_listAppl(v(ML99_add), ML99_nil())

// ML99_appl(v(ML99_add), v(1))
ML99_listAppl(v(ML99_add), ML99_list(v(1)))

// ML99_appl2(v(ML99_add), v(1), v(2))
ML99_listAppl(v(ML99_add), ML99_list(v(1, 2)))
ML99_CONS(x, xs)
ML99_NIL(...)
ML99_IS_CONS(list)
ML99_IS_NIL(list)