TaskEither represents asynchronous computations that may fail. It combines Task and Either, modeling computations that are both asynchronous and may result in errors. TaskEither is right-biased like Either.
Create TaskEither instances for success and failure cases.
/**
* Create TaskEither with left (error) value
* @param l - Error value
* @returns TaskEither that resolves to Left
*/
function left<L, A>(l: L): TaskEither<L, A>;
/**
* Create TaskEither with right (success) value
* @param a - Success value
* @returns TaskEither that resolves to Right
*/
function right<L, A>(a: A): TaskEither<L, A>;
/**
* Create TaskEither from pure value (alias for right)
* @param a - Success value
* @returns TaskEither that resolves to Right
*/
function of<L, A>(a: A): TaskEither<L, A>;
/**
* Create TaskEither from Either
* @param e - Either to lift into Task context
* @returns TaskEither with same left/right value
*/
function fromEither<L, A>(e: Either<L, A>): TaskEither<L, A>;
/**
* Create TaskEither from Task (assumes success)
* @param fa - Task to lift
* @returns TaskEither that cannot fail
*/
function rightTask<L, A>(fa: Task<A>): TaskEither<L, A>;
/**
* Create failing TaskEither from Task
* @param fl - Task containing error value
* @returns TaskEither that always fails
*/
function leftTask<L, A>(fl: Task<L>): TaskEither<L, A>;Usage Examples:
import { left, right, fromEither, rightTask } from "fp-ts/lib/TaskEither";
import { right as eitherRight, left as eitherLeft } from "fp-ts/lib/Either";
import { Task } from "fp-ts/lib/Task";
// Direct construction
const success = right<string, number>(42);
const failure = left<string, number>("Error occurred");
// From Either
const fromEith = fromEither(eitherRight(100));
fromEith.run().then(result => console.log(result)); // Right(100)
// From Task
const asyncTask = new Task(() => Promise.resolve("data"));
const taskEither = rightTask(asyncTask);
taskEither.run().then(result => console.log(result)); // Right("data")Execute functions safely with error handling.
/**
* Safely execute async function that may reject
* @param f - Function returning Promise
* @param onRejected - Function to convert rejection to left value
* @returns TaskEither with result or error
*/
function tryCatch<L, A>(f: Lazy<Promise<A>>, onRejected: (reason: unknown) => L): TaskEither<L, A>;
/**
* Safely execute function that may throw
* @param f - Function that may throw
* @param onThrown - Function to convert thrown value to left value
* @returns TaskEither with result or error
*/
function tryCatchK<L, A>(f: Lazy<A>, onThrown: (e: unknown) => L): TaskEither<L, A>;
/**
* Convert task-returning function to safe TaskEither function
* @param f - Function returning Task
* @param onRejected - Function to convert rejection to left value
* @returns Safe function returning TaskEither
*/
function taskify<L, A, R>(f: (a: A) => Task<R>, onRejected: (reason: unknown) => L): (a: A) => TaskEither<L, R>;Usage Examples:
import { tryCatch, tryCatchK } from "fp-ts/lib/TaskEither";
// Safe fetch
const safeFetch = (url: string) => tryCatch(
() => fetch(url).then(res => res.json()),
(error) => `Fetch failed: ${error}`
);
safeFetch("/api/data").run().then(result => {
if (result._tag === "Right") {
console.log("Data:", result.right);
} else {
console.log("Error:", result.left);
}
});
// Safe JSON parse
const safeParseJSON = (str: string) => tryCatchK(
() => JSON.parse(str),
(error) => `Parse error: ${error}`
);Transform TaskEither computations while preserving the async Either context.
/**
* Map function over right value
* @param f - Transformation function
* @returns Function that maps over TaskEither
*/
function map<A, B>(f: (a: A) => B): <L>(fa: TaskEither<L, A>) => TaskEither<L, B>;
/**
* Map function over left value
* @param f - Transformation function for error
* @returns Function that maps over left value
*/
function mapLeft<L, M>(f: (l: L) => M): <A>(fa: TaskEither<L, A>) => TaskEither<M, A>;
/**
* Map over both left and right values
* @param f - Function for left value
* @param g - Function for right value
* @returns Function that maps over both sides
*/
function bimap<L, M, A, B>(f: (l: L) => M, g: (a: A) => B): (fa: TaskEither<L, A>) => TaskEither<M, B>;Chain TaskEither computations in sequence.
/**
* Chain TaskEither computations (flatMap)
* @param f - Function returning TaskEither
* @returns Function that chains TaskEithers
*/
function chain<L, A, B>(f: (a: A) => TaskEither<L, B>): (fa: TaskEither<L, A>) => TaskEither<L, B>;
/**
* Chain with access to left value on error
* @param f - Function to handle left value
* @returns Function that handles errors
*/
function orElse<L, M, A>(f: (l: L) => TaskEither<M, A>): (fa: TaskEither<L, A>) => TaskEither<M, A>;Usage Examples:
import { chain, map, tryCatch } from "fp-ts/lib/TaskEither";
// Chain operations
const fetchUser = (id: string) => tryCatch(
() => fetch(`/api/users/${id}`).then(res => res.json()),
(error) => `Failed to fetch user: ${error}`
);
const fetchUserPosts = (user: any) => tryCatch(
() => fetch(`/api/users/${user.id}/posts`).then(res => res.json()),
(error) => `Failed to fetch posts: ${error}`
);
const userWithPosts = chain(fetchUserPosts)(fetchUser("123"));
userWithPosts.run().then(result => console.log(result));Pattern match on TaskEither results and extract values.
/**
* Pattern match on TaskEither with handlers for both cases
* @param onLeft - Function to call if result is Left
* @param onRight - Function to call if result is Right
* @returns Function that takes TaskEither and returns Task of result
*/
function fold<L, A, R>(onLeft: (l: L) => R, onRight: (a: A) => R): (fa: TaskEither<L, A>) => Task<R>;
/**
* Extract right value with error handler
* @param f - Function to convert left value to right type
* @returns Function that extracts right value or converts left
*/
function getOrElse<L, A>(f: (l: L) => Task<A>): (fa: TaskEither<L, A>) => Task<A>;
/**
* Extract right value with default Task
* @param onLeft - Default Task for left case
* @returns Function that extracts right or returns default
*/
function getOrElseW<L, B>(onLeft: (l: L) => Task<B>): <A>(fa: TaskEither<L, A>) => Task<A | B>;Usage Examples:
import { fold, getOrElse, right, left } from "fp-ts/lib/TaskEither";
import { Task } from "fp-ts/lib/Task";
const success = right<string, number>(42);
const failure = left<string, number>("Error");
// Pattern matching
const handleResult = fold(
(error: string) => `Failed: ${error}`,
(value: number) => `Success: ${value}`
);
handleResult(success).run().then(result => console.log(result)); // "Success: 42"
// Extract with default
const getValueOrZero = getOrElse((_error: string) => Task.of(0));
getValueOrZero(failure).run().then(result => console.log(result)); // 0Execute multiple TaskEithers in parallel.
/**
* Execute TaskEithers in parallel, collecting results
* @param tasks - Array of TaskEithers to execute
* @returns TaskEither that resolves to array of results (fails if any fail)
*/
function sequenceArray<L, A>(tasks: Array<TaskEither<L, A>>): TaskEither<L, Array<A>>;
/**
* Execute TaskEithers in parallel, transforming with function
* @param f - Function to apply to each element
* @returns Function that maps over array with parallel execution
*/
function traverseArray<L, A, B>(f: (a: A) => TaskEither<L, B>): (as: Array<A>) => TaskEither<L, Array<B>>;TaskEither implements various type class instances.
/**
* Main TaskEither type class instances
*/
const taskEither: Monad2<URI> &
Bifunctor2<URI> &
Alt2<URI> &
MonadIO2<URI> &
MonadTask2<URI> &
MonadThrow2<URI>;
/**
* ApplicativeSeq instance (sequential execution)
*/
const taskEitherSeq: Monad2<URI>;
/**
* Semigroup instance for TaskEither
* @param S - Semigroup for right type
* @returns Semigroup that combines right values
*/
function getSemigroup<L, A>(S: Semigroup<A>): Semigroup<TaskEither<L, A>>;
/**
* Apply semigroup (parallel execution)
* @param S - Semigroup for right type
* @returns Semigroup for parallel combination
*/
function getApplySemigroup<L, A>(S: Semigroup<A>): Semigroup<TaskEither<L, A>>;
/**
* Apply monoid (parallel execution)
* @param M - Monoid for right type
* @returns Monoid for parallel combination
*/
function getApplyMonoid<L, A>(M: Monoid<A>): Monoid<TaskEither<L, A>>;Accumulating validation errors.
/**
* Get validation applicative that accumulates left values
* @param S - Semigroup for left type (error accumulation)
* @returns Applicative that accumulates errors
*/
function getTaskValidation<L>(S: Semigroup<L>): Monad2C<URI, L> & Alt2C<URI, L>;Additional utilities for working with TaskEither.
/**
* Swap left and right values
* @param fa - TaskEither to swap
* @returns TaskEither with swapped left/right
*/
function swap<L, A>(fa: TaskEither<L, A>): TaskEither<A, L>;
/**
* Filter right value with predicate
* @param predicate - Predicate to test right value
* @param onFalse - Value to use if predicate fails
* @returns Function that filters TaskEither
*/
function filterOrElse<L, A>(predicate: Predicate<A>, onFalse: (a: A) => L): (fa: TaskEither<L, A>) => TaskEither<L, A>;
/**
* Apply predicate to right value, converting to left on false
* @param predicate - Predicate to test
* @param onFalse - Function to convert value to left
* @returns Function that converts based on predicate
*/
function fromPredicate<L, A>(predicate: Predicate<A>, onFalse: (a: A) => L): (a: A) => TaskEither<L, A>;// Core TaskEither type
type TaskEither<L, A> = Task<Either<L, A>>;
// URI for type-level programming
const URI = 'TaskEither';
type URI = typeof URI;
// Related types
type Task<A> = import('./Task').Task<A>;
type Either<L, A> = import('./Either').Either<L, A>;