// 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 }