import * as Ap from 'fp-ts/lib/Apply' import * as Eq from 'fp-ts/lib/Eq' import * as O from 'fp-ts/lib/Option' import * as RA from 'fp-ts/lib/ReadonlyArray' export * from 'fp-ts/lib/ReadonlyArray' /** * Unsafely coerce the ReadonlyArray to an Array */ export const unsafeCoerceToArray = ( readonlyArray: ReadonlyArray, ): Array => readonlyArray as Array /** * Unsafely coerce an Array to a ReadonlyArray */ export const unsafeCoerceFromArray = (array: Array): ReadonlyArray => array as ReadonlyArray /** * Gets the head and tail parts of the array as an object, if possible. * * This is often referred to "uncons," as it's the opposite of constructing an array with a head and tail. */ export const headAndTailS = ( a: ReadonlyArray, ): O.Option<{ head: A; tail: ReadonlyArray }> => Ap.sequenceS(O.option)({ head: RA.head(a), tail: RA.tail(a) }) /** * Gets the head and tail parts of the array as a tuple, if possible. * * This is often referred to "uncons," as it's the opposite of constructing an array with a head and tail. */ export const headAndTailT = ( a: ReadonlyArray, ): O.Option<[A, ReadonlyArray]> => Ap.sequenceT(O.option)(RA.head(a), RA.tail(a)) /** * Gets the init and last parts of the array as an object, if possible. * * This is like an "uncons" for the end of the array. */ export const initAndLastS = ( a: ReadonlyArray, ): O.Option<{ init: ReadonlyArray; last: A }> => Ap.sequenceS(O.option)({ init: RA.init(a), last: RA.last(a) }) /** * Gets the init and last parts of the array as a tuple, if possible. * * This is like an "uncons" for the end of the array. */ export const initAndLastT = ( a: ReadonlyArray, ): O.Option<[ReadonlyArray, A]> => Ap.sequenceT(O.option)(RA.init(a), RA.last(a)) /** * Returns an array of elements which are in both input arrays but not in their * intersection. Also known as symmetric difference or disjunctive union. */ export const xor = (eq: Eq.Eq) => ( xs: ReadonlyArray, ys: ReadonlyArray, ) => [...RA.difference(eq)(xs, ys), ...RA.difference(eq)(ys, xs)]