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
Mathematical structures that define operations with specific properties, providing the foundation for generic and composable operations in functional programming.
Associative binary operation - combines two values of the same type.
interface Semigroup<A> {
readonly concat: (x: A, y: A) => A;
}Usage Examples:
import { semigroupSum, semigroupProduct, semigroupString } from "fp-ts/lib/Semigroup";
// Numeric addition
const sum = semigroupSum.concat(5, 10); // 15
// Numeric multiplication
const product = semigroupProduct.concat(3, 4); // 12
// String concatenation
const greeting = semigroupString.concat("Hello", " World"); // "Hello World"
// Custom semigroup for maximum
const semigroupMax: Semigroup<number> = {
concat: (x, y) => Math.max(x, y)
};
const maximum = semigroupMax.concat(3, 7); // 7Semigroup with an identity element (empty/neutral value).
interface Monoid<A> extends Semigroup<A> {
readonly empty: A;
}Built-in Monoids:
/**
* Monoid for number addition (identity: 0)
*/
const monoidSum: Monoid<number>;
/**
* Monoid for number multiplication (identity: 1)
*/
const monoidProduct: Monoid<number>;
/**
* Monoid for string concatenation (identity: "")
*/
const monoidString: Monoid<string>;
/**
* Monoid for boolean AND (identity: true)
*/
const monoidAll: Monoid<boolean>;
/**
* Monoid for boolean OR (identity: false)
*/
const monoidAny: Monoid<boolean>;
/**
* Monoid for void (identity: undefined)
*/
const monoidVoid: Monoid<void>;Usage Examples:
import { monoidSum, monoidString, fold } from "fp-ts/lib/Monoid";
// Identity elements
const zeroSum = monoidSum.empty; // 0
const emptyString = monoidString.empty; // ""
// Fold array with monoid
const numbers = [1, 2, 3, 4, 5];
const total = fold(monoidSum)(numbers); // 15
const words = ["Hello", " ", "World"];
const sentence = fold(monoidString)(words); // "Hello World"
// Empty array folds to identity
const emptySum = fold(monoidSum)([]); // 0Create new monoids from existing ones.
/**
* Dual monoid - reverses the operation order
* @param M - Original monoid
* @returns Monoid with reversed operation
*/
function getDualMonoid<A>(M: Monoid<A>): Monoid<A>;
/**
* Tuple monoid - combines monoids elementwise
* @param MA - Monoid for first element
* @param MB - Monoid for second element
* @returns Monoid for tuples
*/
function getTupleMonoid<A, B>(MA: Monoid<A>, MB: Monoid<B>): Monoid<[A, B]>;
/**
* Record monoid - combines records with monoid per field
* @param monoids - Record of monoids for each field
* @returns Monoid for records
*/
function getStructMonoid<O extends Record<string, any>>(
monoids: { [K in keyof O]: Monoid<O[K]> }
): Monoid<O>;
/**
* Function monoid - combines functions returning monoidal values
* @param M - Monoid for return type
* @returns Monoid for functions
*/
function getFunctionMonoid<M>(M: Monoid<M>): <A>() => Monoid<(a: A) => M>;
/**
* Endomorphism monoid - combines functions from A to A
* @returns Monoid for endomorphisms (function composition)
*/
function getEndomorphismMonoid<A>(): Monoid<Endomorphism<A>>;Usage Examples:
import { getDualMonoid, getTupleMonoid, getStructMonoid } from "fp-ts/lib/Monoid";
import { monoidSum, monoidString } from "fp-ts/lib/Monoid";
// Dual monoid (subtraction instead of addition)
const dualSum = getDualMonoid(monoidSum);
const result1 = dualSum.concat(10, 3); // 3 - 10 = -7
// Tuple monoid
const tupleMonoid = getTupleMonoid(monoidSum, monoidString);
const combined = tupleMonoid.concat([1, "Hello"], [2, " World"]); // [3, "Hello World"]
// Struct monoid
const structMonoid = getStructMonoid({
count: monoidSum,
message: monoidString
});
const merged = structMonoid.concat(
{ count: 1, message: "Hello" },
{ count: 2, message: " World" }
); // { count: 3, message: "Hello World" }Monoid with inverse operation.
interface Group<A> extends Monoid<A> {
readonly inverse: (a: A) => A;
}Structure with two operations: addition and multiplication.
interface Ring<A> extends Semiring<A> {
readonly sub: (x: A, y: A) => A;
}
interface Semiring<A> {
readonly add: (x: A, y: A) => A;
readonly zero: A;
readonly mul: (x: A, y: A) => A;
readonly one: A;
}Built-in Rings:
/**
* Ring for numbers with standard arithmetic
*/
const ringNumber: Ring<number>;Ring with division (multiplicative inverse).
interface Field<A> extends Ring<A> {
readonly degree: (a: A) => number;
readonly div: (x: A, y: A) => A;
readonly mod: (x: A, y: A) => A;
}
/**
* Field for numbers with division
*/
const fieldNumber: Field<number>;Structure with upper and lower bounds.
interface Bounded<A> extends Ord<A> {
readonly top: A;
readonly bottom: A;
}
/**
* Bounded instance for boolean (top: true, bottom: false)
*/
const boundedBoolean: Bounded<boolean>;Structures with join (∨) and meet (∧) operations.
interface JoinSemilattice<A> {
readonly join: (x: A, y: A) => A;
}
interface MeetSemilattice<A> {
readonly meet: (x: A, y: A) => A;
}
interface Lattice<A> extends JoinSemilattice<A>, MeetSemilattice<A> {}
interface BoundedJoinSemilattice<A> extends JoinSemilattice<A> {
readonly zero: A;
}
interface BoundedMeetSemilattice<A> extends MeetSemilattice<A> {
readonly one: A;
}
interface BoundedLattice<A> extends Lattice<A>, BoundedJoinSemilattice<A>, BoundedMeetSemilattice<A> {}
interface DistributiveLattice<A> extends Lattice<A> {}
interface BoundedDistributiveLattice<A> extends BoundedLattice<A>, DistributiveLattice<A> {}Lattice with implication operation.
interface HeytingAlgebra<A> extends BoundedDistributiveLattice<A> {
readonly implies: (x: A, y: A) => A;
readonly not: (a: A) => A;
}
/**
* Heyting algebra for boolean values
*/
const heytingAlgebraBoolean: HeytingAlgebra<boolean>;Heyting algebra where not(not(a)) = a.
interface BooleanAlgebra<A> extends HeytingAlgebra<A> {}
/**
* Boolean algebra for boolean values
*/
const booleanAlgebraBoolean: BooleanAlgebra<boolean>;
/**
* Boolean algebra for void (trivial)
*/
const booleanAlgebraVoid: BooleanAlgebra<void>;Helper functions for working with algebraic structures.
/**
* Fold array using semigroup, returning Option
* @param S - Semigroup instance
* @returns Function that folds non-empty arrays
*/
function fold<A>(S: Semigroup<A>): (as: Array<A>) => Option<A>;
/**
* Get first semigroup (returns first non-empty value)
* @returns Semigroup that prefers first value
*/
function getFirstSemigroup<A>(): Semigroup<Option<A>>;
/**
* Get last semigroup (returns last non-empty value)
* @returns Semigroup that prefers last value
*/
function getLastSemigroup<A>(): Semigroup<Option<A>>;
/**
* Min semigroup using ordering
* @param O - Ordering instance
* @returns Semigroup that returns minimum value
*/
function getMinSemigroup<A>(O: Ord<A>): Semigroup<A>;
/**
* Max semigroup using ordering
* @param O - Ordering instance
* @returns Semigroup that returns maximum value
*/
function getMaxSemigroup<A>(O: Ord<A>): Semigroup<A>;
/**
* Product all numbers in array
* @param ns - Array of numbers
* @returns Product of all numbers (1 for empty array)
*/
function product(ns: Array<number>): number;
/**
* Sum all numbers in array
* @param ns - Array of numbers
* @returns Sum of all numbers (0 for empty array)
*/
function sum(ns: Array<number>): number;Usage Examples:
import { fold, getMinSemigroup, getMaxSemigroup, sum, product } from "fp-ts/lib/Semigroup";
import { ordNumber } from "fp-ts/lib/Ord";
import { some, none } from "fp-ts/lib/Option";
// Fold with semigroup
const minSemigroup = getMinSemigroup(ordNumber);
const numbers = [5, 2, 8, 1, 9];
const minimum = fold(minSemigroup)(numbers); // Some(1)
const emptyMin = fold(minSemigroup)([]); // None
// Utility functions
const total = sum([1, 2, 3, 4, 5]); // 15
const prod = product([2, 3, 4]); // 24
const emptySum = sum([]); // 0
const emptyProd = product([]); // 1