// ets_tracing: off
/* adapted from https://github.com/gcanti/fp-ts */
/**
* Data structure which represents non-empty arrays
*/
import "../../../Operator/index.js"
import type { Predicate, Refinement } from "../../../Function/index.js"
import type { Option } from "../../../Option/index.js"
import { none, some } from "../../../Option/index.js"
import * as A from "../Array/index.js"
import type * as Tp from "../Tuple/index.js"
export type NonEmptyArray = A.Array & {
readonly 0: A
}
/**
* Append an element to the front of an array, creating a new non empty array
*
* @example
* assert.deepStrictEqual(cons(1, [2, 3, 4]), [1, 2, 3, 4])
*/
export const prepend_: (tail: A.Array, head: A) => NonEmptyArray =
A.prepend_ as any
/**
* Append an element to the front of an array, creating a new non empty array
*
* @ets_data_first prepend_
*/
export const prepend: (head: A) => (tail: A.Array) => NonEmptyArray =
A.prepend as any
/**
* Append an element to the end of an array, creating a new non empty array
*
* @example
* assert.deepStrictEqual(snoc([1, 2, 3], 4), [1, 2, 3, 4])
*/
export const append_: (init: A.Array, end: A) => NonEmptyArray =
A.append_ as any
/**
* Append an element to the end of an array, creating a new non empty array
*
* @ets_data_first append_
*/
export const append: (end: A) => (init: A.Array) => NonEmptyArray =
A.append as any
/**
* Builds a `ReadonlyNonEmptyArray` from an array returning `none` if `as` is an empty array
*/
export function fromArray(as: A.Array): Option> {
return A.isNonEmpty(as) ? some(as) : none
}
/**
* Takes the first element
*/
export function head(nea: NonEmptyArray): A {
return nea[0]
}
/**
* Takes the last element
*/
export function tail(nea: NonEmptyArray): A.Array {
return nea.slice(1)
}
/**
* Reverse the array
*/
export const reverse: (nea: NonEmptyArray) => NonEmptyArray = A.reverse as any
/**
* Takes the last element
*/
export function last(nea: NonEmptyArray): A {
return nea[nea.length - 1]!
}
/**
* Get all but the last element of a non empty array, creating a new array.
*
* @example
* assert.deepStrictEqual(init([1, 2, 3]), [1, 2])
* assert.deepStrictEqual(init([1]), [])
*/
export function init(nea: NonEmptyArray): A.Array {
return nea.slice(0, -1)
}
/**
* Insert an element at the specified index, creating a new array,
* or returning None if the index is out of bounds
*
* @ets_data_first insertAt_
*/
export function insertAt(
i: number,
a: A
): (nea: NonEmptyArray) => Option> {
return A.insertAt(i, a) as any
}
/**
* Insert an element at the specified index, creating a new array,
* or returning None if the index is out of bounds
*/
export function insertAt_(
nea: NonEmptyArray,
i: number,
a: A
): Option> {
return A.insertAt_(nea, i, a) as any
}
/**
* Change the element at the specified index,
* creating a new array, or returning None if the index is out of bounds
*
* @ets_data_first updateAt_
*/
export function updateAt(
i: number,
a: A
): (nea: NonEmptyArray) => Option> {
return A.updateAt(i, a) as any
}
/**
* Change the element at the specified index,
* creating a new array, or returning None if the index is out of bounds
*/
export function updateAt_(
nea: NonEmptyArray,
i: number,
a: A
): Option> {
return A.updateAt_(nea, i, a) as any
}
/**
* Apply a function to the element at the specified index,
* creating a new array, or returning None if the index is out of bounds
*
* @ets_data_first modifyAt_
*/
export function modifyAt(
i: number,
f: (a: A) => A
): (nea: NonEmptyArray) => Option> {
return A.modifyAt(i, f) as any
}
/**
* Apply a function to the element at the specified index,
* creating a new array, or returning None if the index is out of bounds
*/
export function modifyAt_(
nea: NonEmptyArray,
i: number,
f: (a: A) => A
): Option> {
return A.modifyAt_(nea, i, f) as any
}
/**
* Filters the array
*
* @ets_data_first filter_
*/
export function filter(
refinement: Refinement
): (nea: NonEmptyArray) => Option>
export function filter(
predicate: Predicate
): (nea: NonEmptyArray) => Option>
export function filter(
predicate: Predicate
): (nea: NonEmptyArray) => Option> {
return (nea) => filter_(nea, predicate)
}
/**
* Filters the array
*/
export function filter_(
nea: NonEmptyArray,
refinement: Refinement
): Option>
export function filter_(
nea: NonEmptyArray,
predicate: Predicate
): Option>
export function filter_(
nea: NonEmptyArray,
predicate: Predicate
): Option> {
return fromArray(A.filter_(nea, predicate))
}
/**
* Filters the array also passing element index
*
* @ets_data_first filterWithIndex_
*/
export function filterWithIndex(
predicate: (i: number, a: A) => boolean
): (nea: NonEmptyArray) => Option> {
return (nea) => fromArray(nea.filter((a, i) => predicate(i, a)))
}
/**
* Filters the array also passing element index
*/
export function filterWithIndex_(
nea: NonEmptyArray,
predicate: (i: number, a: A) => boolean
): Option> {
return fromArray(nea.filter((a, i) => predicate(i, a)))
}
/**
* Construct an array with a single element
*/
export const single: (a: A) => NonEmptyArray = A.single as any
/**
* Concatenate arrays
*/
export function concat_(fx: A.Array, fy: NonEmptyArray): NonEmptyArray
export function concat_(fx: NonEmptyArray, fy: A.Array): NonEmptyArray
export function concat_(fx: A.Array, fy: A.Array): A.Array {
return fx.concat(fy)
}
/**
* Concatenate arrays
*
* @ets_data_first concat_
*/
export function concat(fy: NonEmptyArray): (fx: A.Array) => NonEmptyArray
export function concat(fy: A.Array): (fx: A.Array) => NonEmptyArray
export function concat(fy: A.Array): (fx: A.Array) => A.Array {
return (fx) => fx.concat(fy)
}
/**
* Apply a function to pairs of elements at the same index in two arrays,
* collecting the results in a new array. If one input array is short, excess
* elements of the longer array are discarded.
*/
export const zipWith_: (
fa: NonEmptyArray,
fb: NonEmptyArray,
f: (a: A, b: B) => C
) => NonEmptyArray = A.zipWith_ as any
/**
* Apply a function to pairs of elements at the same index in two arrays,
* collecting the results in a new array. If one input array is short, excess
* elements of the longer array are discarded.
*
* @ets_data_first zipWith_
*/
export const zipWith: (
fb: NonEmptyArray,
f: (a: A, b: B) => C
) => (fa: NonEmptyArray) => NonEmptyArray = A.zipWith as any
/**
* Takes two arrays and returns an array of corresponding pairs.
* If one input array is short, excess elements of the longer array are discarded
*/
export const zip_: (
fa: NonEmptyArray,
fb: NonEmptyArray
) => NonEmptyArray> = A.zip_ as any
/**
* Takes two arrays and returns an array of corresponding pairs.
* If one input array is short, excess elements of the longer array are discarded
*
* @ets_data_first zip_
*/
export const zip: (
fb: NonEmptyArray
) => (fa: NonEmptyArray) => NonEmptyArray> = A.zip as any
/**
* The function is reverse of zip. Takes an array of pairs
* and return two corresponding arrays
*/
export const unzip: (
as: NonEmptyArray>
) => Tp.Tuple<[NonEmptyArray, NonEmptyArray]> = A.unzip as any
/**
* Classic Applicative's ap
*
* @ets_data_first ap_
*/
export const ap: (
fa: NonEmptyArray
) => (fab: NonEmptyArray<(a: A) => B>) => NonEmptyArray = A.ap as any
/**
* Classic Applicative's ap
*/
export const ap_: (
fab: NonEmptyArray<(a: A) => B>,
fa: NonEmptyArray
) => NonEmptyArray = A.ap_ as any
/**
* Composes computations in sequence, using the return value
* of one computation to determine the next computation.
*
* @ets_data_first chain_
*/
export const chain: (
f: (a: A) => NonEmptyArray
) => (ma: NonEmptyArray) => NonEmptyArray = A.chain as any
/**
* Composes computations in sequence, using the return value
* of one computation to determine the next computation.
*/
export const chain_: (
ma: NonEmptyArray,
f: (a: A) => NonEmptyArray
) => NonEmptyArray = A.chain_ as any
/**
* Array[A] => Array[Array[A]]
*/
export const duplicate: (ma: NonEmptyArray) => NonEmptyArray> =
A.duplicate as any
/**
* Extends calls f with all the progressive slices up to the current
* element's index, and uses the return value to construct the result array
*
* i.e: like map that also consumes all the elements up to `i`
*
* @ets_data_first extend_
*/
export const extend: (
f: (fa: NonEmptyArray) => B
) => (ma: NonEmptyArray) => NonEmptyArray = A.extend as any
/**
* Extends calls f with all the progressive slices up to the current
* element's index, and uses the return value to construct the result array
*
* i.e: like map that also consumes all the elements up to `i`
*/
export const extend_: (
ma: NonEmptyArray,
f: (fa: NonEmptyArray) => B
) => NonEmptyArray = A.extend_ as any
/**
* Removes one level of nesting
*/
export const flatten: (mma: NonEmptyArray>) => NonEmptyArray =
A.flatten as any
/**
* Apply f to every element of Array returning Array
*
* @ets_data_first map_
*/
export const map: (f: (a: A) => B) => (fa: NonEmptyArray) => NonEmptyArray =
A.map as any
/**
* Apply f to every element of Array returning Array
*/
export const map_: (fa: NonEmptyArray, f: (a: A) => B) => NonEmptyArray =
A.map_ as any
/**
* Like map but also passes the index to f
*
* @ets_data_first mapWithIndex_
*/
export const mapWithIndex: (
f: (i: number, a: A) => B
) => (fa: NonEmptyArray) => NonEmptyArray = A.mapWithIndex as any
/**
* Like map but also passes the index to f
*/
export const mapWithIndex_: (
fa: NonEmptyArray,
f: (i: number, a: A) => B
) => NonEmptyArray = A.mapWithIndex_ as any
/**
* Construct B by compacting with f over the array from left to right
*
* @ets_data_first reduce_
*/
export const reduce: (b: B, f: (b: B, a: A) => B) => (fa: NonEmptyArray) => B =
A.reduce as any
/**
* Construct B by compacting with f over the array from left to right
*/
export const reduce_: (fa: NonEmptyArray, b: B, f: (b: B, a: A) => B) => B =
A.reduce_ as any
/**
* Construct B by compacting with f over the array from right to left
*
* @ets_data_first reduceRight_
*/
export const reduceRight: (
b: B,
f: (a: A, b: B) => B
) => (fa: NonEmptyArray) => B = A.reduceRight as any
/**
* Construct B by compacting with f over the array from right to left
*/
export const reduceRight_: (
fa: NonEmptyArray,
b: B,
f: (a: A, b: B) => B
) => B = A.reduceRight_ as any
/**
* Construct B by compacting with f over the array from right to left
*
* @ets_data_first reduceRightWithIndex_
*/
export const reduceRightWithIndex: (
b: B,
f: (i: number, a: A, b: B) => B
) => (fa: NonEmptyArray) => B = A.reduceRightWithIndex as any
/**
* Construct B by compacting with f over the array from right to left
*/
export const reduceRightWithIndex_: (
fa: NonEmptyArray,
b: B,
f: (i: number, a: A, b: B) => B
) => B = A.reduceRightWithIndex_ as any
/**
* Construct B by compacting with f over the array from left to right
*
* @ets_data_first reduceWithIndex_
*/
export const reduceWithIndex: (
b: B,
f: (i: number, b: B, a: A) => B
) => (fa: NonEmptyArray) => B = A.reduceWithIndex as any
/**
* Construct B by compacting with f over the array from left to right
*/
export const reduceWithIndex_: (
fa: NonEmptyArray,
b: B,
f: (i: number, b: B, a: A) => B
) => B = A.reduceWithIndex_ as any
/**
* Constructs a NonEmptyArray
*/
export function make]>(
arr: T
): NonEmptyArray {
return arr
}