Task represents asynchronous computations that never fail. Tasks are lazy and only executed when the run() method is called, returning a Promise. For computations that may fail, use TaskEither.
Create Task instances from values and async functions.
/**
* Create Task from pure value
* @param a - Value to wrap in Task
* @returns Task that resolves to the value
*/
function of<A>(a: A): Task<A>;
/**
* Create Task from Promise-returning function
* @param f - Function returning Promise
* @returns Task that executes function when run
*/
function task<A>(f: Lazy<Promise<A>>): Task<A>;
/**
* Create Task from existing Promise
* @param promise - Promise to wrap
* @returns Task that resolves with the Promise
*/
function fromPromise<A>(promise: Promise<A>): Task<A>;
/**
* Never-resolving Task (infinite computation)
*/
const never: Task<never>;
/**
* Create Task that delays execution
* @param millis - Milliseconds to delay
* @returns Task that completes after delay
*/
function delay(millis: number): Task<void>;Usage Examples:
import { Task, of as taskOf, delay } from "fp-ts/lib/Task";
// Pure value
const constantTask = taskOf(42);
constantTask.run().then(result => console.log(result)); // 42
// Async computation
const fetchTask = new Task(() =>
fetch("/api/data").then(res => res.json())
);
// Delayed execution
const delayedTask = delay(1000);
delayedTask.run().then(() => console.log("1 second later"));Transform Task computations while preserving the async context.
/**
* Map function over Task result
* @param f - Transformation function
* @returns Function that maps over Task
*/
function map<A, B>(f: (a: A) => B): (fa: Task<A>) => Task<B>;
/**
* Apply function in Task to value in Task
* @param fab - Task containing function
* @returns Function that applies function to Task value
*/
function ap<A, B>(fab: Task<(a: A) => B>): (fa: Task<A>) => Task<B>;
/**
* Sequence two Tasks, keeping first result
* @param fb - Second Task to execute
* @returns Function that sequences Tasks
*/
function applyFirst<A, B>(fb: Task<B>): (fa: Task<A>) => Task<A>;
/**
* Sequence two Tasks, keeping second result
* @param fb - Second Task to execute
* @returns Function that sequences Tasks
*/
function applySecond<A, B>(fb: Task<B>): (fa: Task<A>) => Task<B>;Usage Examples:
import { Task, map, ap } from "fp-ts/lib/Task";
// Transform result
const numberTask = new Task(() => Promise.resolve(21));
const doubledTask = map((n: number) => n * 2)(numberTask);
doubledTask.run().then(result => console.log(result)); // 42
// Apply function
const addTask = new Task(() => Promise.resolve((x: number) => (y: number) => x + y));
const xTask = new Task(() => Promise.resolve(10));
const yTask = new Task(() => Promise.resolve(20));
const sumTask = ap(ap(addTask)(xTask))(yTask);
sumTask.run().then(sum => console.log(sum)); // 30Chain Task computations in sequence.
/**
* Chain Task computations
* @param f - Function returning Task
* @returns Function that chains Tasks
*/
function chain<A, B>(f: (a: A) => Task<B>): (fa: Task<A>) => Task<B>;
/**
* Flatten nested Task
* @param mma - Task containing Task
* @returns Flattened Task
*/
function flatten<A>(mma: Task<Task<A>>): Task<A>;Usage Examples:
import { Task, chain } from "fp-ts/lib/Task";
// Chain async operations
const getUserId = new Task(() => Promise.resolve("user123"));
const fetchUser = (id: string) => new Task(() =>
fetch(`/api/users/${id}`).then(res => res.json())
);
const userTask = chain(fetchUser)(getUserId);
userTask.run().then(user => console.log(user));Execute multiple Tasks in parallel.
/**
* Execute Tasks in parallel, collecting results
* @param tasks - Array of Tasks to execute
* @returns Task that resolves to array of results
*/
function sequenceArray<A>(tasks: Array<Task<A>>): Task<Array<A>>;
/**
* Execute Tasks in parallel, transforming with function
* @param f - Function to apply to each element
* @returns Function that maps over array with parallel execution
*/
function traverseArray<A, B>(f: (a: A) => Task<B>): (as: Array<A>) => Task<Array<B>>;
/**
* Race multiple Tasks, returning first to complete
* @param tasks - Array of Tasks to race
* @returns Task that resolves with first result
*/
function race<A>(tasks: Array<Task<A>>): Task<A>;Usage Examples:
import { Task, sequenceArray, traverseArray } from "fp-ts/lib/Task";
// Parallel execution
const task1 = new Task(() => Promise.resolve(1));
const task2 = new Task(() => Promise.resolve(2));
const task3 = new Task(() => Promise.resolve(3));
const allTasks = sequenceArray([task1, task2, task3]);
allTasks.run().then(results => console.log(results)); // [1, 2, 3]
// Transform array in parallel
const urls = ["/api/data1", "/api/data2", "/api/data3"];
const fetchUrl = (url: string) => new Task(() => fetch(url).then(res => res.json()));
const allData = traverseArray(fetchUrl)(urls);
allData.run().then(data => console.log(data));Task implements various type class instances for generic operations.
/**
* Main Task type class instances
*/
const task: Monad1<URI> & MonadIO1<URI> & MonadTask1<URI>;
/**
* Semigroup instance for Task
* @param S - Semigroup for contained type
* @returns Semigroup that combines Task results
*/
function getSemigroup<A>(S: Semigroup<A>): Semigroup<Task<A>>;
/**
* Monoid instance for Task
* @param M - Monoid for contained type
* @returns Monoid that combines Task results
*/
function getMonoid<A>(M: Monoid<A>): Monoid<Task<A>>;
/**
* Race-based Monoid (first Task to complete wins)
* @returns Monoid where concat races Tasks
*/
function getRaceMonoid<A>(): Monoid<Task<A>>;Control timing of Task execution.
/**
* Add delay before Task execution
* @param millis - Milliseconds to delay
* @returns Function that delays Task
*/
function delay<A>(millis: number): (fa: Task<A>) => Task<A>;
/**
* Timeout Task execution
* @param millis - Timeout in milliseconds
* @param onTimeout - Value to return on timeout
* @returns Function that adds timeout to Task
*/
function timeout<A>(millis: number, onTimeout: A): (fa: Task<A>) => Task<A>;
/**
* Measure Task execution time
* @param fa - Task to measure
* @returns Task returning tuple of [result, milliseconds]
*/
function time<A>(fa: Task<A>): Task<[A, number]>;Although Task never fails, these utilities help with robust execution.
/**
* Retry Task execution with exponential backoff
* @param maxRetries - Maximum number of retries
* @param delay - Initial delay in milliseconds
* @returns Function that adds retry logic to Task
*/
function retry<A>(maxRetries: number, delay: number): (fa: Task<A>) => Task<A>;
/**
* Execute Task with fallback on failure
* @param fallback - Task to execute if original fails
* @returns Function that adds fallback to Task
*/
function alt<A>(fallback: Task<A>): (fa: Task<A>) => Task<A>;Convert between Task and other effect types.
/**
* Convert IO to Task
* @param ma - IO to convert
* @returns Task that executes IO
*/
function fromIO<A>(ma: IO<A>): Task<A>;
/**
* Convert Task to TaskEither with error handling
* @param f - Task that may reject
* @param onRejected - Function to handle rejection
* @returns TaskEither with proper error handling
*/
function tryCatch<L, A>(f: Lazy<Promise<A>>, onRejected: (reason: unknown) => L): TaskEither<L, A>;Usage Examples:
import { Task, fromIO, tryCatch } from "fp-ts/lib/Task";
import { IO } from "fp-ts/lib/IO";
// Convert IO to Task
const syncIO = new IO(() => "sync result");
const asyncTask = fromIO(syncIO);
asyncTask.run().then(result => console.log(result)); // "sync result"
// Safe async operation
const safeTask = tryCatch(
() => fetch("/api/data").then(res => res.json()),
(error) => `Fetch failed: ${error}`
);// Core Task type
class Task<A> {
readonly _A!: A;
readonly _URI!: URI;
constructor(readonly run: Lazy<Promise<A>>) {}
// Instance methods (deprecated in favor of pipeable operations)
map<B>(f: (a: A) => B): Task<B>;
ap<B>(fab: Task<(a: A) => B>): Task<B>;
chain<B>(f: (a: A) => Task<B>): Task<B>;
// Utility methods
inspect(): string;
toString(): string;
}
// URI for type-level programming
const URI = 'Task';
type URI = typeof URI;
// Lazy Promise type
type Lazy<A> = () => A;