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 and fold_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 where fold_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 evaluating left && right, if left is false, the whole expression will evaluate to false without even evaluating right. 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 of fold_right and the lazy evaluation of Nickel. If we had used fold_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]