std.array
all : forall a. (a -> Bool) -> Array a -> Bool
Returns true
if all elements in the given array satisfy the predicate,
false
otherwise.
Examples
std.array.all (fun x => x < 3) [ 1, 2 ]
# => true
std.array.all (fun x => x < 3) [ 1, 2, 3 ]
# => false
any : forall a. (a -> Bool) -> Array a -> Bool
Returns true
if at least one element in the given array satisfies
the predicate, false
otherwise.
Examples
std.array.any (fun x => x < 3) [ 1, 2, 3, 4 ]
# => true
std.array.any (fun x => x < 3) [ 5, 6, 7, 8 ]
# => false
append : forall a. a -> Array a -> Array a
Builds an array given the last element and the rest of the array.
Examples
std.array.append 3 [ 1, 2 ]
# => [ 1, 2, 3 ]
at : forall a. Number -> Array a -> a
at | std.contract.unstable.IndexedArrayFun 'Index
Retrieves the n-th element from an array, with indices starting at 0.
Examples
std.array.at 3 [ "zero", "one", "two", "three", "four" ]
# => "three"
at_or : forall a. Number -> a -> Array a -> a
at_or | std.number.Nat -> Dyn
Retrieves the n-th element from an array, with indices starting at 0 or the provided default value if the index is greater than the length of the array.
Examples
std.array.at_or 3 "default" [ "zero", "one", "two", "three" ]
# => "three"
std.array.at_or 3 "default" [ "zero", "one" ]
# => "default"
compare : forall
a.
(a -> a -> [| 'Lesser, 'Equal, 'Greater |])
-> Array a -> Array a -> [| 'Lesser, 'Equal, 'Greater |]
compare order a b
lexicographically compares a
and b
, using order
to
compare the individual elements.
Examples
std.array.compare std.number.compare [3, 1, 4] [6, 2, 8]
# => 'Lesser
std.array.compare std.string.compare ["hello", "world"] ["hello"]
# => 'Greater
concat : forall a. Array a -> Array a -> Array a
Appends the second array to the first one.
Examples
std.array.concat [ 1, 2, 3 ] [ 4, 5, 6 ]
# => [ 1, 2, 3, 4, 5, 6 ]
drop_first : forall a. Array a -> Array a
drop_first | NonEmpty -> Dyn
Returns the given array without its first element.
Examples
std.array.drop_first [ 1, 2, 3 ]
# => [ 2, 3 ]
drop_last : forall a. Array a -> Array a
drop_last | NonEmpty -> Dyn
Returns the given array without its last element.
Examples
std.array.drop_last [ 1, 2, 3 ]
# => [ 1, 2 ]
elem : Dyn -> Array Dyn -> Bool
Returns true
if the given value appears in the array, false
otherwise.
Examples
std.array.elem 3 [ 1, 2, 3, 4, 5 ]
# => true
filter : forall a. (a -> Bool) -> Array a -> Array a
filter f xs
returns an array containing all elements from xs
that satisfy f
.
Examples
std.array.filter (fun x => x <= 3) [ 4, 3, 2, 5, 1 ]
# => [ 3, 2, 1 ]
first : forall a. Array a -> a
first | NonEmpty -> Dyn
Returns the first element of an array.
Examples
std.array.first [ "this is the head", "this is not" ]
# => "this is the head"
flat_map : forall a b. (a -> Array b) -> Array a -> Array b
First map
the given function over the array and then flatten
the
result.
Examples
std.array.flat_map (fun x => [x, x]) [1, 2, 3]
# => [1, 1, 2, 2, 3, 3]
flatten : forall a. Array (Array a) -> Array a
Concatenates all elements of an array of arrays.
Examples
std.array.flatten [[1, 2], [3, 4]]
# => [1, 2, 3, 4]
fold_left : forall a b. (a -> b -> a) -> a -> Array b -> a
Folds a function over an array. In a functional language like Nickel,
folds serve a similar purpose to loops or iterators. fold_left
iterates over an array, by repeatedly applying a function to each
element, threading an additional arbitrary state (the accumulator, of
type a
in the signature) through the chain of applications.
fold_left f init [x1, x2, ..., xn]
results in f (... (f (f init x1) x2) ...) xn
.
This function is strict in the intermediate accumulator.
Left vs right
Folds come in two variants, left and right. How to decide which one to use?
-
If the folded function isn't associative (such as subtraction), then each variant will give a different result. The choice is dictacted by which one you need. For example:
std.array.fold_right (-) 0 [1, 2, 3, 4] # => -2
std.array.fold_left (-) 0 [1, 2, 3, 4] # => -10
-
If the folded function is associative, both
fold_right
andfold_left
return the same result. In that case,fold_left
is generally preferred, because it forces the evaluation of the intermediate results resulting in less memory consumption and overall better performance (outside of pathological cases).fold_left
also iterates from the start of the array, which correponds to the usual behavior of loops and iterators in most programming languages. There is one case wherefold_right
might be preferred, see the next point. -
If the folded function is associative but (left) short-circuiting, meaning that it can sometimes determine the result without using the right argument, then
fold_right
provides early return. An example is the boolean AND operator&&
: when evaluatingleft && right
, ifleft
isfalse
, the whole expression will evaluate tofalse
without even evaluatingright
. Consider the following expression:std.array.replicate 1000 true # gives [false, .. true 1000 times] |> std.array.prepend false |> std.array.fold_right (&&) [false]
Here,
fold_right
will stop at the first element, and the operation runs in constant time, given the definition offold_right
and the lazy evaluation of Nickel. If we had usedfold_left
instead, which is closer to a standard iterator, we would have iterated over all of the 1000 elements of the array.
Examples
fold_left (fun acc e => acc + e) 0 [ 1, 2, 3 ]
# => (((0 + 1) + 2) + 3)
# => 6
fold_right : forall a b. (a -> b -> b) -> b -> Array a -> b
Folds a function over an array. Folds serve a similar purpose to loops or
iterators in a functional language like Nickel. fold_right
iterates
over an array by repeatedly applying a function to each element and
threading an additional arbitrary state (the accumulator of type a
in
the signature) through the chain of applications.
fold_right f init [x1, x2, ..., xn]
results in f x1 (f x2 (... (f xn init) ...))
.
Left vs right
Folds come in two variants, left and right. How to decide which one to
use? Please refer to the documentation of fold_left
.
Examples
std.array.fold_right (fun e acc => acc @ [e]) [] [ 1, 2, 3 ]
# => ((([] @ [3]) @ [2]) @ [1])
# => [ 3, 2, 1 ]
generate : forall a. (Number -> a) -> Number -> Array a
generate | Dyn -> std.number.Nat -> Dyn
generate f n
returns an array of length n
by applying f
to the
integers from 0
to n-1
. That is, generate f n
is
[ f 0, f 1, ..., f (n - 1)]
Examples
std.array.generate (fun x => x * x) 4
# => [ 0, 1, 4, 9 ]
intersperse : forall a. a -> Array a -> Array a
Intersperses a value between the elements of an array.
Examples
std.array.intersperse ", " [ "Hello", "wonderful", "world!" ]
# => [ "Hello", ", ", "wonderful", ", ", "world!" ]
std.array.intersperse ", " [ "Hello" ]
# => [ "Hello" ]
std.array.intersperse ", " []
# => []
last : forall a. Array a -> a
last | NonEmpty -> Dyn
Returns the last element of an array.
Examples
std.array.last [ "this is the head", "this is not" ]
# => "this is not"
length : forall a. Array a -> Number
Returns the length of an array.
Examples
std.array.length [ "Hello,", " World!" ]
# => 2
map : forall a b. (a -> b) -> Array a -> Array b
Applies a function to every element in the given array. That is,
map f [ x1, x2, ..., xn ]
is [ f x1, f x2, ..., f xn ]
.
Examples
std.array.map (fun x => x + 1) [ 1, 2, 3 ]
# => [ 2, 3, 4 ]
map_with_index : forall a b. (Number -> a -> b) -> Array a -> Array b
Applies a function to every element in the given array while passing
its (0-based) index. That is,
map_with_index f [ x1, x2, ... ]
is [ f 0 x1, f 1 x2, ... ]
.
Examples
std.array.map_with_index (fun i x => i + x + 1) [ 1, 2, 3 ]
# => [ 2, 4, 6 ]
NonEmpty
Enforces that an array is not empty.
Examples
([] | std.array.NonEmpty)
# => error: contract broken by a value
([ 1 ] | std.array.NonEmpty)
# => [ 1 ]
partition : forall a. (a -> Bool) -> Array a -> { right : Array a, wrong : Array a }
Partitions an array into two new arrays. right
will contain all
elements that satisfy the predicate, while wrong
will contain those
that do not.
Examples
std.array.partition (fun x => x < 5) [ 2, 4, 5, 3, 7, 8, 6 ]
# => { right = [ 2, 4, 3 ], wrong = [ 5, 7, 8, 6 ] }
prepend : forall a. a -> Array a -> Array a
Builds an array given the first element and the rest of the array.
Examples
std.array.prepend 1 [ 2, 3 ]
# => [ 1, 2, 3 ]
range : Number -> Number -> Array Number
range | std.contract.unstable.RangeFun Dyn
range start end
generates the array of numbers
[start, start + 1, start + 2, ..]
up to the first element
(excluded) larger than or equal to end
.
range start end
is equivalent to range_step start end 1
.
Preconditions
In range_step start end
, start
and end
must satisfy
start <= end
.
Examples
std.array.range 0 5
# => [ 0, 1, 2, 3, 4 ]
range_step : Number -> Number -> Number -> Array Number
range_step | std.contract.unstable.RangeFun (std.contract.unstable.RangeStep -> Dyn)
range_step start end step
generates the array of numbers
[start, start + step, start + 2*step, ..]
up to the first element
(excluded) larger than or equal to end
Preconditions
In range_step start end step
, start
and end
must satisfy start <= end
. step
must be strictly greater than 0
.
Examples
std.array.range_step (-1.5) 2 0.5
# => [ -1.5, -1, -0.5, 0, 0.5, 1, 1.5 ]
reduce_left : forall a. (a -> a -> a) -> Array a -> a
reduce_left | Dyn -> NonEmpty -> Dyn
Reduces the elements to a single one, by repeatedly applying a reducing operation.
reduce_left
associates to the left, that is
reduce_left op [x1, x2, ..., xn]
results in op (... (op (op x1 x2) x3) ...) xn
.
reduce_left
is the same as fold_left
, but uses the first element as
the initial accumulator.
Preconditions
The provided array must be non-empty.
Left vs right
The rationale to decide between fold_left
and fold_right
applies to
reduce_left
and reduce_right
as well. See the documentation of
fold_left
.
Examples
std.array.reduce_left (@) [ [1, 2], [3], [4,5] ]
# => (([1, 2] @ [3]) @ [4,5])
# => [ 1, 2, 3, 4, 5 ]
std.array.reduce_left (-) [ 1, 2, 3, 4]
# => ((1 - 2) - 3) - 4
# => -8
reduce_right : forall a. (a -> a -> a) -> Array a -> a
reduce_right | Dyn -> NonEmpty -> Dyn
Reduces the elements to a single one, by repeatedly applying a reducing operation.
reduce_right
associates to the right, that is
reduce_right op [x1, x2, ..., xn]
results in
op x1 (op x2 (... (op xn-1 xn) ...))
.
reduce_right
is the same as fold_right
, but uses the last element as
the initial element.
Preconditions
The provided array must be non-empty.
Left vs right
The rationale to decide between fold_left
and fold_right
applies to
reduce_left
and reduce_right
as well. See the documentation of
fold_left
.
Examples
std.array.reduce_right (@) [ [1, 2], [3], [4,5] ]
# => [1, 2] @ ([3] @ [4,5])
# => [ 1, 2, 3, 4, 5 ]
std.array.reduce_right (-) [ 1, 2, 3, 4]
# => 1 - (2 - (3 - 4))
# => -2
replicate : forall a. Number -> a -> Array a
replicate | std.number.Nat -> Dyn
replicate n x
creates an array containing x
exactly n
times.
Preconditions
n
must be an integer greater or equal to 0
.
Examples
std.array.replicate 0 false
# => [ ]
std.array.replicate 5 "x"
# => [ "x", "x", "x", "x", "x" ]
reverse : forall a. Array a -> Array a
Reverses an array.
Examples
std.array.reverse [ 1, 2, 3 ]
# => [ 3, 2, 1 ]
slice : forall a. Number -> Number -> Array a -> Array a
slice | std.contract.unstable.ArraySliceFun
slice start end array
returns the slice of array
between start
(included) and
end
(excluded).
Preconditions
In slice start end value
, start
and end
must be positive
integers such that 0 <= start <= end <= std.array.length value
.
Examples
std.array.slice 1 3 [ 0, 1, 2, 3, 4, 5]
# => [ 1, 2 ]
std.array.slice 0 3 [ "Hello", "world", "!" ]
# => [ "Hello", "world", "!" ]
std.array.slice 2 3 [ "Hello", "world", "!" ]
# => [ "!" ]
sort : forall a. (a -> a -> [| 'Lesser, 'Equal, 'Greater |]) -> Array a -> Array a
Sorts an array based on the provided comparison operator.
Examples
std.array.sort (fun x y =>
if x < y then
'Lesser
else if (x == y) then
'Equal
else
'Greater)
[ 4, 5, 1, 2 ]
# => [ 1, 2, 4, 5 ]
split_at : forall a. Number -> Array a -> { left : Array a, right : Array a }
split_at | std.contract.unstable.IndexedArrayFun 'Split
Splits an array in two at a given index and puts all the elements
to the left of the element at the given index (excluded) in the
left
field, and the rest of the array in the right
field.
Preconditions
In split_at index value
, index
must be a positive integer such
that 0 <= index <= std.array.length value
.
Examples
std.array.split_at 2 [ 0, 1, 2, 3, 4, 5]
# => { left = [ 0, 1 ], right = [ 2, 3, 4, 5 ] }
std.array.split_at 0 [ "Hello", "world", "!" ]
# => { left = [ ], right = [ "Hello", "world", "!" ] }
std.array.split_at 3 [ "Hello", "world", "!" ]
# => { left = [ "Hello", "world", "!" ], right = [ ] }
try_fold_left : forall
a
b
c.
(a -> c -> [| 'Ok a, 'Error b |]) -> a -> Array c -> [| 'Ok a, 'Error b |]
Folds a function over an array from left to right, possibly stopping early.
This differs from fold_left
in that the function being folded returns either
'Error y
(meaning that the folding should terminate, immediately returning
'Error y
) or 'Ok acc
(meaning that the folding should continue as usual,
with the new accumulator acc
). This early return can be used as an optimization,
to avoid evaluating the whole array.
Examples
This defines a function that returns the first element satisfying a predicate.
let find_first: forall a. (a -> Bool) -> Array a -> [| 'Some a, 'None |]
= fun pred xs =>
# Our fold function, which just ignores the accumulator and immediately
# returns an element if it satisfies the predicate. Note that `'Error`
# (which is the short-circuiting branch) means that we found something.
let f = fun _acc x => if pred x then 'Error x else 'Ok null in
try_fold_left f null xs |> match {
'Ok _ => 'None,
'Error x => 'Some x,
}
in
let even = fun x => x % 2 == 0 in
find_first even [1, 3, 4, 5, 2]
# => 'Some 4
zip_with : forall a b c. (a -> b -> c) -> Array a -> Array b -> Array c
zip_with f xs ys
combines the arrays xs
and ys
using the
operation f
. The resulting array's length will be the smaller of the
lengths of xs
and ys
.
Examples
std.array.zip_with (+) [1, 2, 3] [4, 5, 6]
# => [5, 7, 9]
std.array.zip_with (*) [1, 2] [4, 5, 6]
# => [4, 10]
std.array.zip_with (-) [1, 2, 3] [4, 5]
# => [-3, -3]