import { ListImpl } from './List' ; import { Maybe , Just , Nothing } from './Maybe' ; import { ApKind , ofAp } from './pointfree/ap' ; import { ReplaceFirst , Type , URIS } from './pointfree/hkt' ; import { Tuple } from './Tuple' ; export type NonEmptyArray < T > = T [ ] & { 0 : T ; } ; export interface NonEmptyList < T > extends NonEmptyArray < T > { readonly _URI : NON_EMPTY_LIST_URI ; readonly _A : [ T ] ; traverse < URI extends URIS , AP extends ApKind < any , any > = ApKind < URI , any > > ( of , f ) : Type < URI , ReplaceFirst < AP [ '_A' ] , NonEmptyList < AP [ '_A' ] [ 0 ] > > > ; sequence < Ap extends ApKind < any , any > > ( this , of ) : Type < Ap [ '_URI' ] , ReplaceFirst < Ap [ '_A' ] , NonEmptyList < Ap [ '_A' ] [ 0 ] > > > ; map < U > ( this , callbackfn , thisArg ? ) : NonEmptyList < U > ; chain < U > ( this , callbackfn , thisArg ? ) : NonEmptyList < U > ; reverse ( this ) : NonEmptyList < T > ; ap < R2 > ( other ) : NonEmptyList < R2 > ; joinM < T2 > ( this ) : NonEmptyList < T2 > ; 'fantasy-land/traverse' : this [ 'traverse' ] ; 'fantasy-land/sequence' : this [ 'sequence' ] ; 'fantasy-land/map' : this [ 'map' ] ; 'fantasy-land/chain' : this [ 'chain' ] ; 'fantasy-land/ap' : this [ 'ap' ] ; } export const concat = < T > ( arr ) => ( arr2 ) => arr . concat ( arr2 ) ; export const NON_EMPTY_LIST_URI = 'NonEmptyList' ; export type NON_EMPTY_LIST_URI = typeof NON_EMPTY_LIST_URI ; declare module './pointfree/hkt' { export interface URI2HKT < Types extends any [ ] > { [ NON_EMPTY_LIST_URI ] : NonEmptyList < Types [ 0 ] > ; } } export interface NonEmptyListTypeRef { /** Typecasts an array with at least one element into a `NonEmptyList`. Works only if the compiler can confirm that the array has one or more elements */ < T extends NonEmptyArray < T [ number ] > > ( list ) : NonEmptyList < T [ number ] > ; < T , Rest extends T [ ] > ( value1 , ... values ) : NonEmptyList < T > ; of < T > ( val ) : NonEmptyList < T > ; /** Returns a `Just NonEmptyArray` if the parameter has one or more elements, otherwise it returns `Nothing` */ fromArray < T > ( source ) : Maybe < NonEmptyList < T > > ; /** Converts a `Tuple` to a `NonEmptyArray` */ fromTuple < T , U > ( source ) : NonEmptyArray < T | U > ; /** Typecasts any array into a `NonEmptyArray`, but throws an exception if the array is empty. Use `fromArray` as a safe alternative */ unsafeCoerce < T > ( source ) : NonEmptyArray < T > ; /** Returns true and narrows the type if the passed array has one or more elements */ isNonEmpty < T > ( list ) : list is NonEmptyArray < T > ; /** The same function as \`List#head\`, but it doesn't return a Maybe as a NonEmptyArray will always have a head */ head < T > ( list ) : T ; /** The same function as \`List#last\`, but it doesn't return a Maybe as a NonEmptyArray will always have a last element */ last < T > ( list ) : T ; /** The same function as \`List#tail\`, but it doesn't return a Maybe as a NonEmptyArray will always have a tail (although it may be of length 0) */ tail < T > ( list ) : T [ ] ; } function NonEmptyListConstructor < T > ( list ) ; function NonEmptyListConstructor < T , Rest extends T [ ] > ( value1 , ... values ) ; function NonEmptyListConstructor ( ... args ) { if ( args . length === 1 && Array . isArray ( args [ 0 ] ) && args [ 0 ] . length > 0 ) { return ListImpl . from ( args [ 0 ] ) ; } return ListImpl . of ( ... args ) ; } export const NonEmptyList = Object . assign ( NonEmptyListConstructor , { of : < T > ( val ) => ( new ListImpl ( val ) as unknown ) as NonEmptyList < T > , fromArray : < T > ( source ) : Maybe < NonEmptyList < T > > => NonEmptyList . isNonEmpty ( source ) ? Just ( NonEmptyList ( source ) ) : Nothing , unsafeCoerce : < T > ( source ) : NonEmptyArray < T > => { if ( NonEmptyList . isNonEmpty ( source ) ) { return source ; } throw new Error ( 'NonEmptyList#unsafeCoerce was ran on an empty array' ) ; } , fromTuple : < T , U > ( source ) : NonEmptyArray < T | U > => NonEmptyList ( source . toArray ( ) ) , head : < T > ( list ) : T => list [ 0 ] , last : < T > ( list ) : T => list [ list . length - 1 ] , isNonEmpty : < T > ( list ) : list is NonEmptyArray < T > => list . length > 0 , tail : < T > ( list ) : T [ ] => list . slice ( 1 ) } ) ;