Functional programming library for TypeScript with higher-kinded types, algebraic data types, and type classes
npx @tessl/cli install tessl/npm-fp-ts@1.19.0fp-ts is a library for typed functional programming in TypeScript. It provides essential data types, type classes, and abstractions from functional programming, implementing Higher Kinded Types which TypeScript doesn't natively support. The library enables developers to write pure functional programs with mathematical precision and type safety.
npm install fp-tsimport { option, either, array, io, task, record } from "fp-ts";
import { Option, some, none } from "fp-ts/lib/Option";
import { Either, left, right } from "fp-ts/lib/Either";
import { pipe } from "fp-ts/lib/pipeable";
import { pipeable } from "fp-ts/lib/pipeable";For CommonJS:
const { option, either, array, io, task, record } = require("fp-ts");
const { Option, some, none } = require("fp-ts/lib/Option");
const { Either, left, right } = require("fp-ts/lib/Either");
const { pipe, pipeable } = require("fp-ts/lib/pipeable");import { some, none, Option } from "fp-ts/lib/Option";
import { left, right, Either } from "fp-ts/lib/Either";
import { pipe } from "fp-ts/lib/pipeable";
// Working with optional values
const maybeValue: Option<number> = some(42);
const emptyValue: Option<number> = none;
// Pattern matching
const result = maybeValue.fold(
() => "No value",
(value) => `Value: ${value}`
);
// Working with Either for error handling
const parseNumber = (input: string): Either<string, number> => {
const num = parseInt(input, 10);
return isNaN(num) ? left("Invalid number") : right(num);
};
// Chain operations
const doubled = parseNumber("21")
.map(n => n * 2)
.fold(
error => `Error: ${error}`,
value => `Result: ${value}`
);fp-ts is built around several core concepts:
Safe handling of nullable values with explicit presence/absence modeling.
type Option<A> = Some<A> | None<A>;
function some<A>(a: A): Option<A>;
const none: Option<never>;
function fromNullable<A>(a: A | null | undefined): Option<A>;Modeling computations that may fail with explicit error handling.
type Either<L, A> = Left<L, A> | Right<L, A>;
function left<L, A>(l: L): Either<L, A>;
function right<L, A>(a: A): Either<L, A>;
function fromOption<L>(onNone: L): <A>(fa: Option<A>) => Either<L, A>;Functional array operations with type safety and immutability.
function getMonoid<A>(): Monoid<Array<A>>;
function getEq<A>(E: Eq<A>): Eq<Array<A>>;Synchronous side-effectful computations with explicit effect modeling.
class IO<A> {
constructor(run: () => A);
run(): A;
}
function io<A>(a: A): IO<A>;Asynchronous computations that never fail.
class Task<A> {
constructor(run: () => Promise<A>);
run(): Promise<A>;
}
function task<A>(a: A): Task<A>;Asynchronous computations that may fail with error handling.
type TaskEither<L, A> = Task<Either<L, A>>;
function left<L, A>(l: L): TaskEither<L, A>;
function right<L, A>(a: A): TaskEither<L, A>;
function tryCatch<A>(f: () => Promise<A>): TaskEither<Error, A>;Mathematical abstractions providing generic operations across different data types.
interface Functor<F> {
map: <A, B>(fa: HKT<F, A>, f: (a: A) => B) => HKT<F, B>;
}
interface Monad<F> extends Applicative<F>, Chain<F> {}
interface Semigroup<A> {
concat: (x: A, y: A) => A;
}Core function manipulation and composition utilities.
function identity<A>(a: A): A;
function constant<A>(a: A): () => A;
type Predicate<A> = (a: A) => boolean;
type Refinement<A, B extends A> = (a: A) => a is B;Mathematical structures like Semigroup, Monoid, Group providing composable operations.
interface Semigroup<A> {
concat: (x: A, y: A) => A;
}
interface Monoid<A> extends Semigroup<A> {
empty: A;
}Modern functional programming utilities for chainable operations using the pipe function.
function pipe<A>(a: A): A;
function pipe<A, B>(a: A, ab: (a: A) => B): B;
function pipe<A, B, C>(a: A, ab: (a: A) => B, bc: (b: B) => C): C;
// ... continues up to 10 parameters
function pipeable<F>(I: { URI: F } & I): PipeableOperators<F, I>;Functional utilities for working with JavaScript objects as immutable records.
function map<A, B>(f: (a: A) => B, d: Record<string, A>): Record<string, B>;
function filter<A>(predicate: Predicate<A>, d: Record<string, A>): Record<string, A>;
function collect<A, B>(f: (k: string, a: A) => B, d: Record<string, A>): Array<B>;
function lookup<A>(k: string, d: Record<string, A>): Option<A>;Accumulating validation errors while preserving successful values.
type Validation<L, A> = Either<L, A>;
function getApplicative<L>(S: Semigroup<L>): Applicative2C<URI, L>;
function getAlt<L>(S: Semigroup<L>): Alt2C<URI, L>;// Higher Kinded Types
interface HKT<URI, A> {
readonly _URI: URI;
readonly _A: A;
}
// Option
type Option<A> = Some<A> | None<A>;
class Some<A> {
constructor(readonly value: A);
}
class None<A> {
readonly _tag: 'None';
}
// Either
type Either<L, A> = Left<L, A> | Right<L, A>;
class Left<L, A> {
constructor(readonly value: L);
}
class Right<L, A> {
constructor(readonly value: A);
}
// Function types
type Lazy<A> = () => A;
type Predicate<A> = (a: A) => boolean;
type Refinement<A, B extends A> = (a: A) => a is B;
type Endomorphism<A> = (a: A) => A;