Skip to content
Giulio Canti edited this page Apr 21, 2023 · 18 revisions

FAQ

How can I convert a TaskEither<E, A> into a Task<Either<E, A>>?

No conversion needed, they are the same thing (by definition)

export interface TaskEither<E, A> extends Task<Either<E, A>> {}

What's the difference between ApplyPar and ApplySeq

ApplyPar runs tasks in parallel, ApplySeq runs tasks sequentially

How-to

Problem

How can I go from ReadonlyArray<TaskEither<E, A>> to TaskEither<E, ReadonlyArray<A>>?

Solution

import * as TE from 'fp-ts/TaskEither'

const solution: <E, A>(
  ts: ReadonlyArray<TE.TaskEither<E, A>>
) => TE.TaskEither<E, ReadonlyArray<A>> = TE.sequenceArray

Problem

How can I go from ReadonlyArray<TaskEither<E, A>> to Task<ReadonlyArray<Either<E, A>>>?

Solution

import * as TE from 'fp-ts/TaskEither'
import * as T from 'fp-ts/Task'
import * as E from 'fp-ts/Either'

const solution: <E, A>(
  ts: ReadonlyArray<TE.TaskEither<E, A>>
) => T.Task<ReadonlyArray<E.Either<E, A>>> = T.sequenceArray

Problem

What's the simplest way to console.log the value of a TaskEither<E, A> if the computation is successful?

Solution

import * as Console from 'fp-ts/Console'
import * as TE from 'fp-ts/TaskEither'

export const solution: <E, A>(
  fa: TE.TaskEither<E, A>
) => TE.TaskEither<E, A> = TE.chainFirstIOK(Console.log)

Problem

What's the simplest way to console.log the error of a TaskEither<E, A> if the computation is failed?

Solution

import * as Console from 'fp-ts/Console'
import * as TE from 'fp-ts/TaskEither'

export const solution: <E, A>(
  fa: TE.TaskEither<E, A>
) => TE.TaskEither<E, A> = TE.orElseFirstIOK(Console.log)

Comparison with Promise methods

A table comparing Task / TaskEither with Promise. It assumes the following imports:

import {
  readonlyArray as RA,
  monoid as M,
  task as T,
  taskEither as TE
} from 'fp-ts'
import { pipe, identity } from 'fp-ts/function'
Promise Task TaskEither
Resolve to success Promise.resolve(value) T.of(value) TE.of(value) or TE.right(value)
Resolve to failure Promise.reject(value) N/A TE.left(value)
Transform the result of a task with the function f promise.then(f) pipe(task, T.map(f)) pipe(task, TE.map(f))
Perform a task depending on the result of a previous one promise.then(getPromise) pipe(task, T.flatMap(getTask)) pipe(task, TE.flatMap(getTaskEither))
Execute a list of tasks in parallel Promise.all(promises) T.sequenceArray(tasks) TE.sequenceArray(taskEithers)
Execute a list of tasks in parallel, collecting all failures and successes Promise.allSettled(promises) N/A T.sequenceArray(taskEithers) or pipe(taskEithers, RA.wilt(T.ApplicativePar)(identity))
Execute a list of tasks and succeed/fail with a single value as soon as one of the tasks succeeds/fails Promise.race(promises) M.concatAll(T.getRaceMonoid())(tasks) M.concatAll(T.getRaceMonoid())(taskEithers)