import { Foldable } from "./foldable" ; import { Applicative } from "./applicative" ; import { id , add , compose } from "./utils" ; import { Either , fromEither , right , isRight , isLeft } from "./either" ; export class InfiniteList < A > implements Applicative < A > , Foldable < A > { constructor ( private fn ) { } map < B > ( f ) { return new InfiniteList ( compose ( f , this . fn ) ) ; } mapTo < B > ( b ) { return repeat ( b ) ; } of < B > ( b ) { return repeat ( b ) ; } ap < B > ( a ) { return new InfiniteList ( i => a . fn ( i ) ( this . fn ( i ) ) ) ; } lift < T1 , R > ( f , m ) ; lift < T1 , T2 , R > ( f , m1 , m2 ) ; lift < T1 , T2 , T3 , R > ( f , m1 , m2 , m3 ) ; lift ( ... args ) { return new InfiniteList ( i => { const vals = [ ] ; for ( let j = 1 ; j < args . length ; ++ j ) { vals [ j - 1 ] = args [ j ] . fn ( i ) ; } return args [ 0 ] . apply ( undefined , vals ) ; } ) ; } foldr < B > ( f , init ) { throw new Error ( "Cannot perform strict foldr on infinite list" ) ; } foldl < B > ( f , init ) { throw new Error ( "Cannot perform strict foldl on infinite list" ) ; } shortFoldr < B > ( f , init ) { throw new Error ( "Cannot call shortFoldr on infinite list" ) ; } shortFoldl < B > ( f , init ) { let acc = right ( init ) ; let idx = 0 ; while ( isRight ( acc ) ) { acc = f ( fromEither ( acc ) , this . fn ( idx ) ) ; idx ++ ; } return fromEither ( acc ) ; } size ( ) { return Infinity ; } maximum ( ) { return Infinity ; } minimum ( ) { return 0 ; } sum ( ) { return Infinity ; } } export function repeat < A > ( a ) { return new InfiniteList ( _ => a ) ; } export const naturals = new InfiniteList ( id ) ;