import { pipe } from 'fp-ts/function' ; import * as TE from 'fp-ts/TaskEither' ; interface User { } function getUsersByPage ( page ) { return Promise . resolve ( page < 3 ? [ 'a' , 'b' ] : [ ] ) ; } const getUsers = ( page ) : TE . TaskEither < Error , ReadonlyArray < User > > => TE . tryCatch ( ( ) => getUsersByPage ( page ) , ( ) => new Error ( `Error while fetching page: ${ page }` ) ) ; const step = ( page , users ) : TE . TaskEither < Error , ReadonlyArray < User > > => pipe ( getUsers ( page ) , TE . chain ( ( result ) => result . length === 0 ? TE . of ( users ) : step ( page + 1 , users . concat ( result ) ) ) ) ; export const getAllUsers = step ( 0 , [ ] ) ; import * as assert from 'assert' ; import * as E from 'fp-ts/Either' ; async function test ( ) { assert . deepStrictEqual ( await getAllUsers ( ) , E . right ( [ 'a' , 'b' , 'a' , 'b' , 'a' , 'b' ] ) ) ; } test ( ) ;