Appearance
aivi.list
The aivi.list module provides a comprehensive set of functions for working with lists. Lists in AIVI are ordered, immutable sequences of values. All operations return new lists — no mutation ever occurs.
aivi
use aivi.list (
isEmpty
length
map
filter
find
sortBy
)Two built-in functions underpin all list work and are available everywhere without importing:
| Function | Signature | Description |
|---|---|---|
append | List A -> List A -> List A | Concatenate two lists |
reduce | (B -> A -> B) -> B -> List A -> B | Fold a list from left to right |
Inspection
Functions that query the structure or contents of a list without changing it.
isEmpty
Returns True if the list has no elements.
aivi
isEmpty : (List A) -> Boolaivi
use aivi.list (isEmpty)
type List Int -> Text
func describe = items => isEmpty items
T|> "empty list"
F|> "has elements"
value result : Text = describe []
value result2 : Text =
describe [
1,
2
]nonEmpty
Returns True if the list has at least one element.
aivi
nonEmpty : (List A) -> Boolaivi
use aivi.list (nonEmpty)
type List Int -> Text
func describeList = items => nonEmpty items
T|> "has elements"
F|> "empty"
value result : Text =
describeList [
42
]length
Returns the number of elements in a list.
aivi
length : (List A) -> Intaivi
use aivi.list (length)
value n : Int =
length [
10,
20,
30
]head
Returns the first element wrapped in Some, or None if the list is empty.
aivi
head : (List A) -> Option Aaivi
use aivi.list (head)
type List Int -> Int
func firstOrZero = items => head items
||> None -> 0
||> Some n -> n
value result : Int =
firstOrZero [
5,
10,
15
]
value fallback : Int = firstOrZero []at
Returns the element at the given zero-based index wrapped in Some, or None if the index is negative or out of range.
aivi
at : Int -> (List A) -> Option Aaivi
use aivi.list (at)
value items : List Text = [
"alpha",
"beta",
"gamma"
]
value middle : Option Text = at 1 items
value missing : Option Text = at 9 itemstail
Returns all elements after the first, wrapped in Some (List A), or None if the list is empty.
aivi
tail : (List A) -> Option (List A)aivi
use aivi.list (tail)
type List Int -> List Int
func restOrEmpty = items => tail items
||> None -> []
||> Some remaining -> remaining
value result : List Int =
restOrEmpty [
1,
2,
3
]tailOrEmpty
Returns all elements after the first, or [] if the list is empty. A convenient alternative to tail when None handling is not needed.
aivi
tailOrEmpty : (List A) -> List Aaivi
use aivi.list (tailOrEmpty)
value rest : List Int =
tailOrEmpty [
1,
2,
3
]
value none : List Int = tailOrEmpty []last
Returns the last element wrapped in Some, or None if the list is empty.
aivi
last : (List A) -> Option Aaivi
use aivi.list (last)
type List Int -> Int
func finalScore = scores => last scores
||> None -> 0
||> Some n -> n
value result : Int =
finalScore [
80,
90,
95
]Transformation
Functions that produce a new list from an existing one.
map
Applies a function to every element, returning a new list of the results.
aivi
map : (A -> B) -> (List A) -> List Baivi
use aivi.list (map)
type Int -> Int
func double = n =>
n * 2
value result : List Int = [1, 2, 3]
|> map doublefilter
Returns only the elements that satisfy a predicate.
aivi
filter : (A -> Bool) -> (List A) -> List Aaivi
use aivi.list (filter)
type Int -> Bool
func isPositive = n =>
n > 0
value resultflatten
Collapses a list of lists into a single flat list.
aivi
flatten : (List (List A)) -> List Aaivi
use aivi.list (flatten)
value nested : List (List Int) = [
[1, 2],
[3, 4],
[5]
]
value flat : List Int = flatten nestedflatMap
Applies a function returning a list to each element, then flattens the result. Equivalent to map followed by flatten.
aivi
flatMap : (A -> List B) -> (List A) -> List Baivi
use aivi.list (flatMap)
type Int -> List Int
func twice = n =>
[n, n]
value result : List Int = [1, 2, 3]
|> flatMap twicereverse
Returns the list with its elements in reversed order.
aivi
reverse : (List A) -> List Aaivi
use aivi.list (reverse)
value original : List Int = [
1,
2,
3,
4,
5
]
value reversed : List Int = reverse originaltake
Returns the first n elements. If the list is shorter than n, the entire list is returned.
aivi
take : Int -> (List A) -> List Aaivi
use aivi.list (take)
value items : List Int = [
10,
20,
30,
40,
50
]
value first3 : List Int = take 3 itemsdrop
Skips the first n elements and returns the rest.
aivi
drop : Int -> (List A) -> List Aaivi
use aivi.list (drop)
value items : List Int = [
10,
20,
30,
40,
50
]
value after2 : List Int = drop 2 itemsreplaceAt
Returns a new list with the element at the given zero-based index replaced. Negative or out-of-range indices leave the original list unchanged.
aivi
replaceAt : Int -> A -> (List A) -> List Aaivi
use aivi.list (replaceAt)
value items : List Int = [
10,
20,
30
]
value updated : List Int = replaceAt 1 99 items
value unchanged : List Int = replaceAt 9 42 itemstakeWhile
Returns the longest prefix of elements that all satisfy the predicate. Stops at the first element that does not match.
aivi
takeWhile : (A -> Bool) -> (List A) -> List Aaivi
use aivi.list (takeWhile)
type Int -> Bool
func isSmall = n =>
n < 10
value result : List Int = [2, 5, 8, 11, 3]
|> takeWhile isSmalldropWhile
Drops elements from the front as long as they satisfy the predicate, then returns the rest.
aivi
dropWhile : (A -> Bool) -> (List A) -> List Aaivi
use aivi.list (dropWhile)
type Int -> Bool
func isSmall = n =>
n < 10
value result : List Int = [2, 5, 8, 11, 3]
|> dropWhile isSmallintersperse
Inserts a separator element between every pair of adjacent elements.
aivi
intersperse : A -> (List A) -> List Aaivi
use aivi.list (intersperse)
value words : List Text = [
"one",
"two",
"three"
]
value spaced : List Text = intersperse ", " wordsSearching
Functions that locate elements or test properties of a list.
any
Returns True if at least one element satisfies the predicate.
aivi
any : (A -> Bool) -> (List A) -> Boolaivi
use aivi.list (any)
type Int -> Bool
func isNegative = n =>
n < 0
value resultall
Returns True if every element satisfies the predicate.
aivi
all : (A -> Bool) -> (List A) -> Boolaivi
use aivi.list (all)
type Int -> Bool
func isPositive = n =>
n > 0
value allPositive : Bool =
all isPositive [
1,
2,
3
]
value someNegcount
Returns the number of elements that satisfy the predicate.
aivi
count : (A -> Bool) -> (List A) -> Intaivi
use aivi.list (count)
type Int -> Bool
func isPositive = n =>
n > 0
value nfind
Returns the first element that satisfies the predicate, or None.
aivi
find : (A -> Bool) -> (List A) -> Option Aaivi
use aivi.list (find)
type User = {
id: Int,
name: Text
}
type Int -> User -> Bool
func hasId = target user =>
user.id == target
type Int -> List User -> Option User
func findUser = id users =>
find (hasId id) usersfindMap
Applies a function to each element in order and returns the first Some result, or None if all calls return None. Useful for combined search-and-transform.
aivi
findMap : (A -> Option B) -> (List A) -> Option Baivi
use aivi.list (findMap)
type Int -> Option Int
func asPositive = n => n > 0
T|> Some n
F|> None
value resultcontains
Returns True if any element equals the target, using the provided equality function.
aivi
contains : (A -> A -> Bool) -> A -> (List A) -> Boolaivi
use aivi.list (contains)
type Int -> Int -> Bool
func intEq = a b =>
a == b
value found : Bool =
contains intEq 3 [
1,
2,
3,
4,
5
]
value missing : Bool =
contains intEq 9 [
1,
2,
3
]indexOf
Returns the index of the first element satisfying the predicate, or None.
aivi
indexOf : (A -> Bool) -> (List A) -> Option Intaivi
use aivi.list (indexOf)
type Int -> Bool
func isThirty = n =>
n == 30
value idx : Option Int =
indexOf isThirty [
10,
20,
30,
40
]Aggregation
Functions that reduce a list to a single value.
sum
Sums all integers in a list. Returns 0 for an empty list.
aivi
sum : (List Int) -> Intaivi
use aivi.list (sum)
value total : Int =
sum [
1,
2,
3,
4,
5
]product
Multiplies all integers in a list together. Returns 1 for an empty list.
aivi
product : (List Int) -> Intaivi
use aivi.list (product)
value result : Int =
product [
1,
2,
3,
4,
5
]maximum
Returns the largest element wrapped in Some, or None for an empty list. Requires a comparison function cmp where cmp a b = True means a is less than b.
aivi
maximum : (A -> A -> Bool) -> (List A) -> Option Aaivi
use aivi.list (maximum)
type Int -> Int -> Bool
func isLess = a b =>
a < b
value highest : Option Int =
maximum isLess [
3,
1,
4,
1,
5,
9,
2,
6
]minimum
Returns the smallest element wrapped in Some, or None for an empty list. Accepts the same kind of comparison function as maximum.
aivi
minimum : (A -> A -> Bool) -> (List A) -> Option Aaivi
use aivi.list (minimum)
type Int -> Int -> Bool
func isLess = a b =>
a < b
value lowest : Option Int =
minimum isLess [
3,
1,
4,
1,
5,
9,
2,
6
]Set Operations
Functions that treat lists as ordered collections with identity constraints.
unique
Removes duplicate elements, keeping only the first occurrence of each. Requires an equality function.
aivi
unique : (A -> A -> Bool) -> (List A) -> List Aaivi
use aivi.list (unique)
type Int -> Int -> Bool
func intEq = a b =>
a == b
value deduped : List Int =
unique intEq [
1,
2,
1,
3,
2,
4
]sortBy
Sorts a list using an ordering function. The function cmp a b should return True when a should appear before b in the result.
aivi
sortBy : (A -> A -> Bool) -> (List A) -> List Aaivi
use aivi.list (sortBy)
type Int -> Int -> Bool
func intLt = a b =>
a < b
value sorted : List Int =
sortBy intLt [
3,
1,
4,
1,
5,
9
]For descending order, reverse the comparison:
aivi
use aivi.list (sortBy)
type Int -> Int -> Bool
func intGt = a b =>
a > b
value descending : List Int =
sortBy intGt [
3,
1,
4,
1,
5,
9
]partition
Splits a list into two sub-lists: matched (elements satisfying the predicate) and unmatched (those that do not). Preserves the original order in both sub-lists.
aivi
partition : (A -> Bool) -> (List A) -> Partition APartition A is a record { matched: List A, unmatched: List A }.
aivi
use aivi.list (
Partition
partition
)
type Int -> Bool
func isPositive = n =>
n > 0
value groups
value positive : (List Int) = groups.matched
value negative : (List Int) = groups.unmatchedZipping
Functions that combine multiple lists element-by-element.
zip
Pairs up elements from two lists into a list of tuples. The result length equals the shorter of the two inputs.
aivi
zip : (List A) -> (List B) -> List (A, B)aivi
use aivi.list (zip)
value names : List Text = [
"Alice",
"Bob",
"Carol"
]
value scores : List Int = [
95,
87,
92
]
value pairs : List (Text, Int) = zip names scoreszipWith
Like zip, but instead of producing tuples it applies a combining function to each pair of elements.
aivi
zipWith : (A -> B -> C) -> (List A) -> (List B) -> List Caivi
use aivi.list (zipWith)
type Int -> Int -> Int
func add = a b =>
a + b
value sums : List Int =
zipWith add [1, 2, 3] [
10,
20,
30
]unzip
Separates a list of pairs into two separate lists. The inverse of zip.
aivi
unzip : (List (A, B)) -> UnzipState A BUnzipState A B is a record { lefts: List A, rights: List B }.
aivi
use aivi.list (
UnzipState
unzip
)
type UnzipState Text Int -> (List Text)
func takeLefts = state => state
||> { lefts, rights } -> lefts
type UnzipState Text Int -> (List Int)
func takeRights = state => state
||> { lefts, rights } -> rights
value pairs : List (Text, Int) = [
("Alice", 95),
("Bob", 87),
("Carol", 92)
]
value result : (UnzipState Text Int) = unzip pairs
value names : (List Text) = takeLefts result
value scores : (List Int) = takeRights result