Skip to content

@oofp/core

@oofp/core is the foundation of the OOFP ecosystem. It provides algebraic data types, function composition utilities, collection helpers, type classes, and a Higher-Kinded Types system — all with zero runtime dependencies.

Terminal window
pnpm add @oofp/core

License: MIT | Zero dependencies | Tree-shakeable — import only what you use.


The core data types for modeling effects in your programs.

ModuleImportDescription
Maybe@oofp/core/maybeOptional values without null or undefined
Either@oofp/core/eitherTyped success or failure
Task@oofp/core/taskLazy asynchronous computation
TaskEither@oofp/core/task-eitherAsync computation that can fail
Reader@oofp/core/readerComputation that requires context (dependency injection)
ReaderTaskEither@oofp/core/reader-task-eitherDI + async + error handling — the main workhorse
IO@oofp/core/ioSynchronous side effects
State@oofp/core/stateStateful computation

Utilities for building data pipelines and composing functions.

ModuleImportDescription
pipe@oofp/core/pipeLeft-to-right value transformation (up to 25 steps)
flow@oofp/core/flowLeft-to-right function composition (up to 12 steps)
compose@oofp/core/composeRight-to-left function composition (up to 26 steps)
import { pipe } from "@oofp/core/pipe";
import { flow } from "@oofp/core/flow";
import { compose } from "@oofp/core/compose";

Functional operations on built-in data structures.

ModuleImportDescription
list@oofp/core/listArray utilities (reduceRight, grouping, etc.)
object@oofp/core/objectObject utilities
string@oofp/core/stringString utilities

Standalone helpers that complement the core data types.

ModuleImportDescription
curry@oofp/core/curryAutomatic function currying
memo@oofp/core/memoMemoization
id@oofp/core/idIdentity function
promise@oofp/core/promisePromise utilities
ref@oofp/core/refMutable references with lens-based focusing
profunctor@oofp/core/profunctorProfunctor for input/output mapping
bi-compose@oofp/core/bi-composeBi-directional composition

Monad transformers for composing effects.

ModuleImportDescription
MaybeT@oofp/core/maybe-tMaybe transformer — wraps Maybe inside any monad

ModuleImportDescription
utils@oofp/core/utilsShared utilities (concurrency, sequence, etc.)

Abstract interfaces that describe capabilities. See Type Classes & HKT for details.

ModuleImportDescription
functor@oofp/core/functorFunctor, Functor2, Functor3, BiFunctor2
applicative@oofp/core/applicativeApplicative, Applicative2, Applicative3
monad@oofp/core/monadMonad, Monad2, Monad3
chain@oofp/core/chainChain, Chain2, Chain3
join@oofp/core/joinJoinable, Joinable2, Joinable3
pointed@oofp/core/pointedPointed, Pointed2, Pointed3
delayable@oofp/core/delayableDelayable, Delayable2, Delayable3
or-else@oofp/core/or-elseOrElse2, OrElse3

The encoding system for generic programming over type constructors.

ModuleImportDescription
URIS@oofp/core/URISURItoKind<A>, URIS, Kind<F, A> — for 1-parameter types
URIS2@oofp/core/URIS2URItoKind2<E, A>, URIS2, Kind2<F, E, A> — for 2-parameter types
URIS3@oofp/core/URIS3URItoKind3<R, E, A>, URIS3, Kind3<F, R, E, A> — for 3-parameter types

import { pipe } from "@oofp/core/pipe";
import * as RTE from "@oofp/core/reader-task-either";
import * as TE from "@oofp/core/task-either";
import * as E from "@oofp/core/either";
interface AppContext {
db: { findUser: (id: string) => Promise<User> };
}
const getUser = (id: string): RTE.ReaderTaskEither<AppContext, Error, User> =>
pipe(
RTE.ask<AppContext>(),
RTE.chaint((ctx) =>
TE.tryCatch(
() => ctx.db.findUser(id),
(err) => new Error(`User not found: ${err}`),
),
),
);
// Execute at the boundary
const result = await pipe(
getUser("42"),
RTE.run({ db: myDbClient }),
)();
pipe(
result,
E.fold(
(err) => console.error(err.message),
(user) => console.log(user),
),
);