Base

Builtin functions, types, and interfaces.

Provides baseline functionality that is automatically included in all modules. All functions are in the global namespace and can be accessed directly without any prefix.

Index

NameTypeDescription

print(a)

A -> ()

Prints any value a by calling to_pretty() on it and outputting the result to stdout.

debug(a, prefix)

(A, String) -> A

Prints any value a just like print(), but prefixes it with the given prefix, and returns a.

to_str(a)

A -> String

Converts any value a into a string.

to_pretty(a)

A -> String

Converts any value a into a string, exactly like to_str(), but if the result is long, adds newlines and tabbing to make it easy to read.

fail(a)

A -> B

Raises a Fail exception described by the given argument, which can be of any type.

interface Sized

T ~ Sized

The Sized interface represents a type that has a length.

length(sized)

T ~ Sized -> Int

Returns the length of sized.

empty?(sized)

T ~ Sized -> Bool

Returns whether sized is empty.

interface Concat

T ~ Concat

The Concat interface lets you concatenate/merge two values of a given type into a single value.

concat(a, b)

(T ~ Concat, T ~ Concat) -> T ~ Concat

Concatenates a and b together, equivalent to a ++ b.

concat_all(l)

[T ~ Concat] -> T ~ Concat

Concatenates all elements in the list l together.

interface Mappable

T<A> ~ Mappable

The Mappable interface represents a generic type T such that we can map T<A> to T<B> with a mapping function A -> B.

map(container, f)

(T<A> ~ Mappable, A -> B) -> T<B> ~ Mappable

Calls f for each element in container, collecting the results into a new container.

interface Collection

T<A> ~ Collection

The Collection interface represents a generic container type that can hold many elements.

fold(collection, init, f)

(T<A> ~ Collection, F, (F, A) -> F) -> F

Computes a single value by applying the combining function f to each element of the given collection, starting with the initial value init.

filter(collection, f)

(T<A> ~ Collection, A -> Bool) -> T<A> ~ Collection

Calls f for each element in collection, returning a new collection that only contains the elements for which f returns true.

find(collection, f)

(T<A> ~ Collection, A -> Bool) -> Option<A>

Returns the first element in collection for which f returns true.

filter_map(collection, f)

(T<A> ~ Collection, A -> Option<B>) -> T<B> ~ Collection

Calls f for each element in collection, returning a new collection that contains every e such that f returned Some(e).

fold_map(collection, init, f)

(T<A> ~ Collection, F, (F, A) -> (F, B)) -> (F, T<B> ~ Collection)

Computes a new collection and a single value by applying the combining function f to each element of the given collection, starting with the initial value init.

put(collection, elem)

(T<A> ~ Collection, A) -> T<A> ~ Collection

Puts elem into collection, returning a new collection.

delete(collection, elem)

(T<A> ~ Collection, A) -> T<A> ~ Collection

Removes elem from collection, returning a new collection.

contains?(collection, elem)

(T<A> ~ Collection, A) -> Bool

Returns true if collection contains elem.

all?(collection, f)

(T<A> ~ Collection, A -> Bool) -> Bool

Calls f for each element in collection, and returns true if f returns true for every element.

any?(collection, f)

(T<A> ~ Collection, A -> Bool) -> Bool

Calls f for each element in collection, and returns true if f returns true for at least one element.

head(l)

[A] -> A

Returns the first element in the list l.

tail(l)

[A] -> [A]

Returns a list containing all elements in l except the first.

get(m, k)

(Map<K, V>, K) -> V

Returns the value associated with key k in the map m.

lookup(m, k)

(Map<K, V>, K) -> Option<V>

If key k is in the map m, returns Some(v), where v is the value associated with k.

key?(m, k)

(Map<K, V>, K) -> Bool

Returns true if the key k is in map m.

remove(m, k)

(Map<K, V>, K) -> Map<K, V>

Removes the key k and its associated value from m, returning a new map.

first(t)

((A, B)) -> A

Returns the first element in the tuple t.

second(t)

((A, B)) -> B

Returns the second element in the tuple t.

some_or(option, default)

(Option<A>, A) -> A

If option is Some(a), returns a.

abs(a)

A ~ Num -> A ~ Num

Returns the absolute value of a.

ceil(a)

Float -> Int

Returns the smallest integer that is greater than or equal to a.

floor(a)

Float -> Int

Returns the largest integer that is less than or equal to a.

max(a)

(A ~ Ord, A ~ Ord) -> A ~ Ord

Returns the maximum of a and b.

min(a, b)

(A ~ Ord, A ~ Ord) -> A ~ Ord

Returns the minimum of a and b.

round(a)

Float -> Int

Rounds a to the nearest integer.

trunc(a)

Float -> Int

Removes anything after the decimal point in a, returning an integer.

interface ToInt

T ~ ToInt

The ToInt interface represents a type that can be converted to an integer.

to_int(a)

T ~ ToInt -> Int

Converts a to an integer.

interface ToFloat

T ~ ToFloat

The ToFloat interface represents a type that can be converted to a float.

to_float(a)

T ~ ToFloat -> Float

Converts a to a float.

interface ToChar

T ~ ToChar

The ToChar interface represents a type that can be converted to a character.

to_char(a)

T ~ ToChar -> Char

Converts a to a character.

interface ToAtom

T ~ ToAtom

The ToAtom interface represents a type that can be converted to an atom.

to_atom(a)

T ~ ToAtom -> Atom

Converts a to an atom.

interface ToList

T<A> ~ ToList

The ToList interface represents a generic type that can be converted to a list.

to_list(a)

T<A> ~ ToList -> [A]

Converts a to a list.

interface ToSet

T<A> ~ ToSet

The ToSet interface represents a generic type that can be converted to a set.

to_set(a)

T<A> ~ ToSet -> Set<A>

Converts a to a set.

interface ToMap

T<K, V> ~ ToMap

The ToMap interface represents a generic type that can be converted to a map.

to_map(a)

T<K, V> ~ ToMap -> Map<K, V>

Converts a to a map.

enum Option<T>

Option<T>

Represents an optional value of type T.

Functions

print : A -> ()
print(a)

Prints any value a by calling to_pretty() on it and outputting the result to stdout.

// outputs hello
print("hello")

// outputs { foo = "hi", bar => true }
print({ foo = "hi", bar => true })

// outputs [37.8]
print([37.8])
debug : (A, String) -> A
debug(a, prefix)

Prints any value a just like print(), but prefixes it with the given prefix, and returns a. debug() is meant to be used with the pipe operator |> in the middle of expressions. For instance, given the expression foo('a', bar("baz", false), 27.5), if you're debugging and want to print the second argument, you can write foo('a', bar("baz", false) |> debug("bar"), 27.5). This'll print bar: ..., where ... is the return value of the bar function call.

// outputs length: 2
length([true, false]) |> debug("length")

// outputs b: 15
get("b", { "a" => 37.5, "b" => 15 }) |> debug("b")
to_str : A -> String
to_str(a)

Converts any value a into a string. Most values are represented as they would appear in code, but there are a few exceptions:

  • Characters are internally stored as integers by their unicode codepoint, so their string representation is numeric; e.g. to_str('a') == "65". If you'd like to convert a Char or [Char] to a String containing those characters (e.g. convert 'a' to "a" or ['h', 'i'] to "hi"), use String.from_chars().
  • Atoms are represented without the leading @, so to_str(@hey) == "hey".
  • A tuple with an atom as the first element, like (@Some, 3), is converted to look like an enum variant: "Some(3)". This is because enum variants are internally represented as tuples in this form.

Atoms should rarely be used in Par, except when interoperating with Erlang, so the latter two exceptions should rarely cause issues. The main case that may cause surprise is characters.

assert to_str(1) == "1"
assert to_str(true) == "true"
assert to_str(@hey) == "hey"
assert to_str('c') == "99"
assert to_str("hi") == "hi"
assert to_str([true, false]) == "[true, false]"

let str = to_str({ a = 8.7, foo = @hello })
// order is undefined
assert str == "{ a = 8.7, foo = hello }" ||
  str == "{ foo = hello, a = 8.7 }"
to_pretty : A -> String
to_pretty(a)

Converts any value a into a string, exactly like to_str(), but if the result is long, adds newlines and tabbing to make it easy to read.

let tuple = (
  27,
  0.138,
  false,
  @hello,
  '\n',
  (523.81, true, @sub_tuple, 's'),
  ["first", "second", "third"]
)
assert to_pretty(tuple) == "(\n" ++
  "  27,\n" ++
  "  0.138,\n" ++
  "  false,\n" ++
  "  hello,\n" ++
  "  10,\n" ++
  "  (523.81, true, sub_tuple, 115),\n" ++
  "  [\"first\", \"second\", \"third\"]\n" ++
")"
fail : A -> B
fail(a)

Raises a Fail exception described by the given argument, which can be of any type. By convention, this exception isn't meant to be caught; create your own exception if you intend for it to be caught and handled.

// Raises a Fail("couldn't perform action") exception.
fail("couldn't perform action")

Returns the first element in the list l. Raises EmptyList if l is empty.

assert head([1]) == 1
assert head(["hi", "hey", "hello"]) == "hi"
tail : [A] -> [A]
tail(l)

Returns a list containing all elements in l except the first. Raises EmptyList if l is empty.

assert tail([1]) == []
assert tail(["hi", "hey", "hello"]) == ["hey", "hello"]
get : (Map<K, V>, K) -> V
get(m, k)

Returns the value associated with key k in the map m. If k isn't in m, raises BadKey.

assert get({ "bar" => 3.7, "baz" => 1 }, "baz") == 1
assert get({ 'h' => false }, 'h') == false
lookup : (Map<K, V>, K) -> Option<V>
lookup(m, k)

If key k is in the map m, returns Some(v), where v is the value associated with k. Otherwise, returns None.

assert lookup({ "bar" => 3.7, "baz" => 1 }, "foo") == None
assert lookup({ 'h' => false }, 'h') == Some(false)
assert lookup({}, true) == None
key? : (Map<K, V>, K) -> Bool
key?(m, k)

Returns true if the key k is in map m.

assert key?({ "bar" => 3.7, "baz" => 1 }, "baz")
assert !key?({ 'h' => false }, 'g')
assert !key?({}, true)
remove : (Map<K, V>, K) -> Map<K, V>
remove(m, k)

Removes the key k and its associated value from m, returning a new map. m is not modified.

assert remove({ "bar" => 3.7, "baz" => 1 }, "baz") == { "bar" => 3.7 }
assert remove({ 'h' => false }, 'h') == {}
assert remove({ 'h' => false }, 'g') == { 'h' => false }
assert remove({}, true) == {}
first : ((A, B)) -> A
first(t)

Returns the first element in the tuple t.

assert first((1, 2)) == 1
assert first(('a', true)) == 'a'
second : ((A, B)) -> B
second(t)

Returns the second element in the tuple t.

assert second((1, 2)) == 2
assert second(('a', true)) == true
some_or : (Option<A>, A) -> A
some_or(option, default)

If option is Some(a), returns a. Otherwise, if option is None, returns default.

assert some_or(Some(0.48), 21.3) == 0.48
assert some_or(None, 'h') == 'h'
abs : A ~ Num -> A ~ Num
abs(a)

Returns the absolute value of a.

assert abs(1) == 1
assert abs(-1) == 1
assert abs(-35.8) == 35.8
ceil : Float -> Int
ceil(a)

Returns the smallest integer that is greater than or equal to a.

assert ceil(38.1) == 39
assert ceil(38) == 38
assert ceil(-38.1) == -38
assert ceil(-38.9) == -38
floor : Float -> Int
floor(a)

Returns the largest integer that is less than or equal to a.

assert floor(38.9) == 38
assert floor(38) == 38
assert floor(-38.1) == -39
assert floor(-38.9) == -39
max : (A ~ Ord, A ~ Ord) -> A ~ Ord
max(a)

Returns the maximum of a and b.

assert max(3, 7) == 7
assert max(-3, -7) == -3
min : (A ~ Ord, A ~ Ord) -> A ~ Ord
min(a, b)

Returns the minimum of a and b.

assert min(3, 7) == 3
assert min(-3, -7) == -7
round : Float -> Int
round(a)

Rounds a to the nearest integer.

assert round(-8.4) == -8
assert round(1.5) == 2
trunc : Float -> Int
trunc(a)

Removes anything after the decimal point in a, returning an integer.

assert trunc(-8.6) == -8
assert trunc(1.9) == 1

Interfaces

interface Sized

The Sized interface represents a type that has a length. The types String, [A], Set<A>, and Map<K, V> implement the Sized interface.

interface Sized {
  length : T -> Int
  empty? : T -> Bool
}
length : T ~ Sized -> Int
length(sized)

Returns the length of sized.

If sized is a string, the length is the number of characters (more specifically, the number of unicode codepoints).

If sized is a list or set, the length is the number of elements.

If sized is a map, the length is the number of key-value pairs.

assert length("abc") == 3
assert length("") == 0
assert length(['a', 'b']) == 2
assert length([]) == 0
assert length(#[3.7]) == 1
assert length(#[]) == 0
assert length({ true => @hi, false => @hey }) == 2
assert length({}) == 0
empty? : T ~ Sized -> Bool
empty?(sized)

Returns whether sized is empty. "" is an empty string, [] is an empty list, #[] is an empty set, and {} is an empty map. This is equivalent to when length() returns 0, but avoids computing the full length in various cases.

assert !empty?("abc")
assert empty?("")
assert !empty?(['a', 'b'])
assert empty?([])
assert !empty?(#[3.7])
assert empty?(#[])
assert !empty?({ true => @hi, false => @hey })
assert empty?({})
interface Concat

The Concat interface lets you concatenate/merge two values of a given type into a single value. The types String, [A], Set<A> and Map<K, V> implement the Concat interface.

interface Concat {
  concat : (T, T) -> T
  concat_all : [T] -> T
}
concat : (T ~ Concat, T ~ Concat) -> T ~ Concat
concat(a, b)

Concatenates a and b together, equivalent to a ++ b.

For strings and lists, the result contains the characters/elements of a followed by the characters/elements of b.

For sets, merges (unions) a and b together, returning a new set.

For maps, merges a and b together, returning a new map. If a key exists in both a and b, the value in b takes precedence.

assert concat("hello ", "world") == "hello world"
assert concat("foo", "bar") == "foobar"
assert concat(["cow", "dog", "cat"], ["turtle"]) ==
  ["cow", "dog", "cat", "turtle"]
assert concat([42.3, .428], [13.3, 5]) == [42.3, .428, 13.3, 5]
assert concat(#[1, 3, 5], #[3, 5, 6]) == #[1, 3, 5, 6]
assert concat(#['a', 'b'], #['c', 'd', 'e', 'f']) ==
  #['a', 'b', 'c', 'd', 'e', 'f']
assert concat({ "foo" => 7.5 }, { "bar" => 3.7, "baz" => 1 }) ==
  { "foo" => 7.5, "bar" => 3.7, "baz" => 1 }
assert concat({ true => 'i', false => 'y' }, { true => 'h' }) ==
  { true => 'h', false => 'y' }
concat_all : [T ~ Concat] -> T ~ Concat
concat_all(l)

Concatenates all elements in the list l together. If l is [a, b, c, ...], this is equivalent to a ++ b ++ c ++ .... See concat() for how a single concatenation works.

assert concat_all(["hello ", "world", "foo", "bar"]) ==
  "hello worldfoobar"
assert concat_all([["cow", "dog", "cat"], ["turtle"], [], ["rat"]]) ==
  ["cow", "dog", "cat", "turtle", "rat"]
assert concat_all([#[1, 3, 5], #[3, 5, 6], #[10], #[5, 10, 3]]) ==
  #[1, 3, 5, 6, 10]
assert concat_all([
  { "foo" => 7.5 }
  { "bar" => 3.7, "baz" => 1 }
  { "baz" => 20 }
  { "foo" => 13.1 }
]) == { "foo" => 13.1, "bar" => 3.7, "baz" => 20 }
interface Mappable

The Mappable interface represents a generic type T such that we can map T<A> to T<B> with a mapping function A -> B. We call T a container type, whereas A and B are element types. Mappable lets us map a container type with element type A to the same container type with a different element type B. The container types List, Set, Map, and Option implement Mappable.

interface Mappable {
  map : (T<A>, A -> B) -> T<B>
}
map : (T<A> ~ Mappable, A -> B) -> T<B> ~ Mappable
map(container, f)

Calls f for each element in container, collecting the results into a new container.

If container is a list, the order of the mapped elements mirrors the order of the original elements. If collection is a set or map, the order is undefined.

If container is of type Map<K, V>, f must accept a tuple of type (K, V), representing a single key-value pair, and return a tuple of type (L, M) for some L and M, representing a new key-value pair. The resultant type is then Map<L, M>.

If container is of type Option<T>, and container == None, the return value is None. If container is Some(a), the return value is Some(f(a)).

assert map(Some(3), |a| a + 1) == Some(4)
assert map(None, |a| a + 1) == None
assert map([@hi, @hey], |a| a == @hey) == [false, true]
assert map([], |a| a == @hey) == []
assert map(#[{ ch = 'a' }, { ch = 'b' }], .ch) == #['a', 'b']
assert map(#[], .ch) == #[]
assert map({ true => @hi }, |(k, v)| (v, k)) == { @hi => true }
assert map({}, |(k, v)| (v, k)) == {}
interface Collection extends Mappable

The Collection interface represents a generic container type that can hold many elements. The types List, Set, and Map implement Collection.

interface Collection extends Mappable {
  fold : (T<A>, F, (F, A) -> F) -> F
  filter : (T<A>, A -> Bool) -> T<A>
  find : (T<A>, A -> Bool) -> Option<A>
  filter_map : (T<A>, A -> Option<B>) -> T<B>
  fold_map : (T<A>, F, (F, A) -> (F, B)) -> (F, T<B>)
  put : (T<A>, A) -> T<A>
  delete : (T<A>, A) -> T<A>
  contains? : (T<A>, A) -> Bool
  all? : (T<A>, A -> Bool) -> Bool
  any? : (T<A>, A -> Bool) -> Bool
}
fold : (T<A> ~ Collection, F, (F, A) -> F) -> F
fold(collection, init, f)

Computes a single value by applying the combining function f to each element of the given collection, starting with the initial value init. This is also called a reduce, accumulate, or inject operation.

Calls f(accum, e) for each element e in the given collection. For the first element, accum is init. For each subsequent element, accum is the return value of the last call to f. So accum is computed across multiple calls to f, and the final value of accum after all elements have been processed is the return value of fold.

Put another way, fold() lets you build up an accumulated value by incrementally computing it based on the current element, and the previously accumulated value.

If collection is a list, fold() processes elements in order. If collection is a set or map, the order is undefined.

If collection is of type Map<K, V>, f's first argument, e, will be a tuple of type (K, V), representing the current key-value pair.

assert fold([1, 2, 3], 10, |accum, a| accum + a) == 16
assert fold([], 10, |accum, a| accum + a) == 10
assert fold(#[1, 2, 3], 10, |accum, a| accum + a) == 16
assert fold(#[], 10, |accum, a| accum + a) == 10

let m = { 1 => 2, 3 => 4, 5 => 6 }
assert fold(m, 10, |accum, (k, v)| accum + k + v) == 31

assert fold({}, 10, |accum, (k, v)| accum + k + v) == 10
filter : (T<A> ~ Collection, A -> Bool) -> T<A> ~ Collection
filter(collection, f)

Calls f for each element in collection, returning a new collection that only contains the elements for which f returns true.

If collection is a list, the returned collection maintains the order of elements in the original collection. If collection is a set or map, the order is undefined.

If collection is of type Map<K, V>, f should accept an argument of type (K, V), representing a key-value pair.

assert filter(["cat", "dog", "mouse"], |a| a < "lion") == ["cat", "dog"]
assert filter([], |a| a < "lion") == []
assert filter(#["cat", "dog", "mouse"], |a| a < "lion") ==
  #["cat", "dog"]
assert filter(#[], |a| a < "lion") == #[]

let m = { "cat" => @cat, "dog" => @dog, "mouse" => @mouse }
assert filter(m, |(k, v)| k < "lion" && v == @dog) == { "dog" => @dog }

assert filter({}, |(k, v)| k < "lion" && v == @dog) == {}
find : (T<A> ~ Collection, A -> Bool) -> Option<A>
find(collection, f)

Returns the first element in collection for which f returns true.

If collection is a list, processes elements in order. If collection is a set or map, the order is undefined.

If collection is of type Map<K, V>, f should accept an argument of type (K, V), representing a key-value pair.

assert find(['c', 'z', 'g'], |a| a > 'e') == Some('z')
assert find(['c', 'a'], |a| a > 'e') == None

let found = find(#['c', 'z', 'g'], |a| a > 'e')
// order is undefined
assert found == Some('z') || found == Some('g')

assert find(#['c', 'a'], |a| a > 'e') == None

let found = find({
  'c' => true
  'z' => false
  'g' => false
}, |(k, v)| k > 'e' && !v)
// order is undefined
assert found == Some(('z', false)) || found == Some(('g', false))

assert find(#['c', 'a'], |a| a > 'e') == None
filter_map : (T<A> ~ Collection, A -> Option<B>) -> T<B> ~ Collection
filter_map(collection, f)

Calls f for each element in collection, returning a new collection that contains every e such that f returned Some(e). This performs a filter() and map() operation at the same time. For elements that should be filtered out, f should return None, and for elements that need to be mapped, f should return Some(e), where e is the new element in the resulting collection.

If collection is a list, the order of the mapped elements mirrors the order of the original elements. If collection is a set or map, the order is undefined.

If collection is of type Map<K, V>, f should accept an argument of type (K, V), representing a key-value pair.

assert filter_map([true, false], |a| if a then Some([a]) else None) ==
  [[true]]
assert filter_map([], |a| if a then Some([a]) else None) == []
assert filter_map(#[true, false], |a| if a then Some([a]) else None) ==
  #[[true]]
assert filter_map(#[], |a| if a then Some([a]) else None) == #[]

let m = { true => [true], false => [false] }
assert filter_map(m, |(k, v)| if k then Some((v, k)) else None) ==
  { [true] => true }

assert filter_map({}, |(k, v)| if k then Some((v, k)) else None) == {}
fold_map : (T<A> ~ Collection, F, (F, A) -> (F, B)) -> (F, T<B> ~ Collection)
fold_map(collection, init, f)

Computes a new collection and a single value by applying the combining function f to each element of the given collection, starting with the initial value init. This performs a map() and fold() operation at the same time.

Calls f(accum, e) for each element e in the given collection. f returns a tuple (new_accum, new_e). The new_es are collected into a new collection.

For the first element, accum is init. For each subsequent element, accum is the new_accum returned from the last call to f. So accum is computed across multiple calls to f. The final value of accum after all elements have been processed, along with the collection of new_es, is the return value of fold_map().

If collection is of type Map<K, V>, f's first argument, e, will be a tuple of type (K, V), representing the current key-value pair.

assert fold_map(["hi", "bye"], "-", |accum, a|
  (accum ++ a, a ++ "!")
) == ("-hibye", ["hi!", "bye!"])
assert fold_map([], "-", |accum, a|
  (accum ++ a, a ++ "!")
) == ("-", [])

let (final, mapped) = fold_map(#["hi", "bye"], "-", |accum, a|
  (accum ++ a, a ++ "!")
)
assert mapped == #["hi!", "bye!"]
// order is undefined
assert final == "-hibye" || final == "-byehi"

assert fold_map(#[], "-", |accum, a|
  (accum ++ a, a ++ "!")
) == ("-", #[])

let m = { "hi" => "now", "bye" => "later" }
let (final, mapped) = fold_map(m, "-", |accum, (k, v)|
  (accum ++ k ++ v, (k ++ "!", v ++ "!"))
)
assert mapped == { "hi!" => "now!", "bye!" => "later!" }
// order is undefined
assert final == "-hinowbyelater" || final == "-byelaterhinow"

assert fold_map({}, "-", |accum, (k, v)|
  (accum ++ k ++ v, (k ++ "!", v ++ "!"))
) == ("-", {})
put : (T<A> ~ Collection, A) -> T<A> ~ Collection
put(collection, elem)

Puts elem into collection, returning a new collection. The original collection is not modified.

If collection is a list, elem is added to the front of the list.

If collection is of type Map<K, V>, the second argument to put should be a tuple of type (K, V), representing one key-value pair.

assert put(["second"], "first") == ["first", "second"]
assert put([], "first") == ["first"]
assert put(#["second"], "first") == #["first", "second"]
assert put(#[], "first") == #["first"]
assert put({ "second" => 2 }, ("first", 1)) ==
  { "first" => 1, "second" => 2 }
assert put({}, ("first", 1)) == { "first" => 1 }
delete : (T<A> ~ Collection, A) -> T<A> ~ Collection
delete(collection, elem)

Removes elem from collection, returning a new collection. The original collection is not modified. If collection doesn't contain elem, does nothing and returns the original collection.

To delete a key from a map, use remove(), not delete(). delete() works with maps, but it requires a tuple of type (K, V) as the second argument. meaning you need to pass both the key and its associated value, which isn't what you usually want.

assert delete([38.52, 1.7, 4, 1.7], 1.7) == [38.52, 4]
assert delete([38.52, 1.7, 4, 1.7], 37.0) == [38.52, 1.7, 4, 1.7]
assert delete(#[38.52, 1.7, 4, 1.7], 1.7) == #[38.52, 4]
assert delete(#[], 37.0) == #[]
assert delete({ 38.52 => 1.7, 4 => 2.9 }, (38.52, 1.7)) == { 4 => 2.9 }
assert delete({ 38.52 => 1.7, 4 => 2.9 }, (4, 3)) ==
  { 38.52 => 1.7, 4 => 2.9 }
contains? : (T<A> ~ Collection, A) -> Bool
contains?(collection, elem)

Returns true if collection contains elem.

To check if a key is contained within a map, use key?(), not contains?(). contains?() works with maps, but it accepts a tuple of type (K, V) as the second argument, meaning you need to pass both the key and its associated value, which isn't usually what you want.

assert contains?([38.52, 1.7, 4, 1.7], 1.7)
assert !contains?([38.52, 1.7, 4, 1.7], 37.0)
assert contains?(#[38.52, 1.7, 4, 1.7], 1.7)
assert !contains?(#[38.52, 1.7, 4, 1.7], 37.0)
assert contains?({ 38.52 => 1.7, 4 => 2.9 }, (38.52, 1.7))
assert !contains?({}, (38.52, 1.7))
all? : (T<A> ~ Collection, A -> Bool) -> Bool
all?(collection, f)

Calls f for each element in collection, and returns true if f returns true for every element. If collection is empty, returns true.

If collection is of type Map<K, V>, f should accept an argument of type (K, V), representing a key-value pair.

assert all?(['a', 'e', 'a'], |x| x == 'a' || x == 'e')
assert !all?(['a', 'e', 'a'], |x| x == 'a' || x == 'i')
assert all?([], |x| x)
assert all?(#['a', 'e', 'a'], |x| x == 'a' || x == 'e')
assert !all?(#['a', 'e', 'a'], |x| x == 'a' || x == 'i')
assert all?({ 'a' => 1, 'e' => 2 }, |(k, v)|
  (k == 'a' || k == 'e') && v > 0
)
assert !all?({ 'a' => 1, 'e' => 2 }, |(k, v)|
  (k == 'a' || k == 'e') && v > 1
)
any? : (T<A> ~ Collection, A -> Bool) -> Bool
any?(collection, f)

Calls f for each element in collection, and returns true if f returns true for at least one element. If collection is empty, returns false.

If collection is of type Map<K, V>, f should accept an argument of type (K, V), representing a key-value pair.

assert any?(['a', 'e', 'a'], |x| x == 'e' || x == 'i')
assert !any?(['a', 'e', 'a'], |x| x == 'o' || x == 'i')
assert !any?([], |x| x == 'e' || x == 'i')
assert any?(#['a', 'e', 'a'], |x| x == 'e' || x == 'i')
assert !any?(#['a', 'e', 'a'], |x| x == 'o' || x == 'i')
assert any?({ 'a' => 1, 'e' => 2 }, |(k, v)| k == 'a' || v > 2)
assert !any?({ 'a' => 1, 'e' => 2 }, |(k, v)| k == 'i' || v > 2)
interface ToInt

The ToInt interface represents a type that can be converted to an integer. The types Float, Char, String, and [Char] implement the ToInt interface.

interface ToInt {
  to_int : T -> Int
}
to_int : T ~ ToInt -> Int
to_int(a)

Converts a to an integer.

If a is a float, this is equivalent to trunc. If a is a character, returns the unicode codepoint of a.

If a is of type String or [Char], tries to parse an integer from the characters in a. Raises CantParseInt if a is empty or contains non-numeric characters.

assert to_int(3.7) == 3
assert to_int('a') == 97
assert to_int(['1', '3', '5']) == 135
assert to_int("83") == 83
interface ToFloat

The ToFloat interface represents a type that can be converted to a float. The types Int, String, and [Char] implement the ToFloat interface.

interface ToFloat {
  to_float : T -> Float
}
to_float : T ~ ToFloat -> Float
to_float(a)

Converts a to a float.

If a is an integer, returns the floating point representation of a.

If a is of type String or [Char], tries to parse an integer from the characters in a. Raises CantParseInt if a is empty or contains non-numeric characters.

assert to_float(3 : Int) == 3.0
assert to_float(['1', '.', '3', '5']) == 1.35
assert to_float("2") == 2.0
assert to_float("83.0") == 83.0
assert to_float(".37") == .37
interface ToChar

The ToChar interface represents a type that can be converted to a character. The type Int implements the ToChar interface.

interface ToChar {
  to_char : T -> Char
}
to_char : T ~ ToChar -> Char
to_char(a)

Converts a to a character.

If a is an integer, representing a unicode codepoint, returns the character corresponding to that codepoint.

assert to_char(97 : Int) == 'a'
assert to_char(10 : Int) == '\n'
interface ToAtom

The ToAtom interface represents a type that can be converted to an atom. The types Char, String, and [Char] implements the ToAtom interface.

interface ToAtom {
  to_atom : T -> Atom
}
to_atom : T ~ ToAtom -> Atom
to_atom(a)

Converts a to an atom.

If a is a character, returns the atom containing just that character.

If a is of type String or [Char], returns the atom containing the characters given by a.

assert to_atom('a') == @a
assert to_atom(['h', 'i']) == @hi
assert to_atom("hello") == @hello
interface ToList

The ToList interface represents a generic type that can be converted to a list. The types Set and Map implement the ToList interface.

interface ToList {
  to_list : T<A> -> [A]
}
to_list : T<A> ~ ToList -> [A]
to_list(a)

Converts a to a list.

If a is a set, the resultant list will contain all elements of a, but the order of those elements is undefined.

If a is of type Map<K, V>, the resultant list will contain tuples of type (K, V), each representing a key-value pair in a. The order of the tuples is undefined.

let l = to_list(#[1, 2])
// order is undefined
assert l == [1, 2] || l == [2, 1]

let l = to_list({ "hey" => true, "hi" => false })
// order is undefined
assert l == [("hey", true), ("hi", false)] ||
  l == [("hi", false), ("hey", true)]
interface ToSet

The ToSet interface represents a generic type that can be converted to a set. The types List and Map implement the ToSet interface.

interface ToSet {
  to_set : T<A> -> Set<A>
}
to_set : T<A> ~ ToSet -> Set<A>
to_set(a)

Converts a to a set.

If a is a list, the resultant set will contain all elements of a.

If a is of type Map<K, V>, the resultant set will contain tuples of type (K, V), each representing a key-value pair in a.

assert to_set([1, 2]) == #[1, 2]
assert to_set({ "hey" => true, "hi" => false }) ==
  #[("hey", true), ("hi", false)]
assert to_set({}) == #[]
interface ToMap

The ToMap interface represents a generic type that can be converted to a map. The types List and Set implement the ToMap interface.

interface ToMap {
  to_map : T<K, V> -> Map<K, V>
}
to_map : T<K, V> ~ ToMap -> Map<K, V>
to_map(a)

Converts a to a map.

If a is a list or set, a must contain tuples of type (K, V) for some K and V, each representing a key-value pair. The return value will be of type Map<K, V>.

If a is a list, and there are multiple elements in a with the same key, the last element's value will overwrite the others.

If a is a set, and there are multiple elements in a with the same key, the value that takes precedence is undefined, as sets are unordered.

assert to_map([(1, "one"), (2, "two")]) == { 1 => "one", 2 => "two" }
assert to_map([]) == {}
assert to_map(#[("hey", true), ("hi", false)]) ==
  { "hey" => true, "hi" => false }

Implementations

impl Mappable for Option

The following functions are from the Mappable interface.

map : (Option<A>, A -> B) -> Option<B>
map(container, f)

Calls f for each element in container, collecting the results into a new container. See the full description in the Mappable interface.

impl ToInt for Float

The following functions are from the ToInt interface.

to_int : Float -> Int
to_int(a)

Converts a to an integer. See the full description in the ToInt interface.

impl ToFloat for Int

The following functions are from the ToFloat interface.

to_float : Int -> Float
to_float(a)

Converts a to a float. See the full description in the ToFloat interface.

impl ToChar for Int

The following functions are from the ToChar interface.

to_char : Int -> Char
to_char(a)

Converts a to a character. See the full description in the ToChar interface.

Types

enum Option<T>

Represents an optional value of type T. None means no value, similar to the concept of null in other languages, and Some(T) means there is a value of type T.

enum Option<T> {
  None
  Some(T)
}

Exceptions

exception EmptyList

Raised by head() and tail() if the list is empty.

exception BadKey

Raised by get() when a key isn't in a map.

exception CantParseInt(String)

Raised by to_int() when an Int can't be parsed from a String. This can happen if the string is empty or contains non-numeric characters.

exception CantParseFloat(String)

Raised by to_float() when a Float can't be parsed from a String. This can happen if the string is empty or contains non-numeric characters.

exception Fail(String)

Raised by fail() when there's an unexpected runtime exception, as described by the String argument. By convention, this exception isn't meant to be caught; create your own exception if you intend for it to be caught and handled.