Functional programming library for TypeScript with higher-kinded types, algebraic data types, and type classes
—
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Pending
The risk profile of this skill
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>;