CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-fp-ts

Functional programming library for TypeScript with higher-kinded types, algebraic data types, and type classes

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

pipeable.mddocs/

Pipeable Operations

The pipeable module provides modern functional programming utilities for chainable operations using the pipe function and pipeable operator style. This is the recommended modern approach for using fp-ts, offering better type inference and composition than traditional method chaining.

Core Imports

import { pipe } from "fp-ts/lib/pipeable";
import { pipeable } from "fp-ts/lib/pipeable";

Capabilities

Pipe Function

The fundamental composition function that enables left-to-right function application, replacing nested function calls with readable pipelines.

/**
 * Pipe function for left-to-right function composition
 * Supports up to 10 function compositions with full type safety
 */
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;
function pipe<A, B, C, D>(a: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D): D;
// ... continues up to 10 parameters

Usage Examples:

import { pipe } from "fp-ts/lib/pipeable";
import { map, filter, fold } from "fp-ts/lib/Array";
import { some, none, fold as optionFold } from "fp-ts/lib/Option";

// Array processing pipeline
const result = pipe(
  [1, 2, 3, 4, 5],
  filter((n: number) => n > 2),
  map((n: number) => n * 2),
  fold(0, (acc: number, n: number) => acc + n)
);
// Result: 18

// Option processing pipeline
const maybeDouble = pipe(
  some(21),
  map((n: number) => n * 2),
  optionFold(
    () => "No value",
    (value: number) => `Value: ${value}`
  )
);
// Result: "Value: 42"

Pipeable Interfaces

Type-safe interfaces that provide pipeable versions of common functional operations for all data types that support them.

Functor Operations

interface PipeableFunctor<F> {
  readonly map: <A, B>(f: (a: A) => B) => (fa: HKT<F, A>) => HKT<F, B>;
}

interface PipeableFunctor1<F extends URIS> {
  readonly map: <A, B>(f: (a: A) => B) => (fa: Kind<F, A>) => Kind<F, B>;
}

interface PipeableFunctor2<F extends URIS2> {
  readonly map: <A, B>(f: (a: A) => B) => <L>(fa: Kind2<F, L, A>) => Kind2<F, L, B>;
}

Apply Operations

interface PipeableApply<F> extends PipeableFunctor<F> {
  readonly ap: <A>(fa: HKT<F, A>) => <B>(fab: HKT<F, (a: A) => B>) => HKT<F, B>;
  readonly apFirst: <B>(fb: HKT<F, B>) => <A>(fa: HKT<F, A>) => HKT<F, A>;
  readonly apSecond: <B>(fb: HKT<F, B>) => <A>(fa: HKT<F, A>) => HKT<F, B>;
}

Chain (Monad) Operations

interface PipeableChain<F> extends PipeableApply<F> {
  readonly chain: <A, B>(f: (a: A) => HKT<F, B>) => (ma: HKT<F, A>) => HKT<F, B>;
  readonly chainFirst: <A, B>(f: (a: A) => HKT<F, B>) => (ma: HKT<F, A>) => HKT<F, A>;
  readonly flatten: <A>(mma: HKT<F, HKT<F, A>>) => HKT<F, A>;
}

Foldable Operations

interface PipeableFoldable<F> {
  readonly reduce: <A, B>(b: B, f: (b: B, a: A) => B) => (fa: HKT<F, A>) => B;
  readonly foldMap: <M>(M: Monoid<M>) => <A>(f: (a: A) => M) => (fa: HKT<F, A>) => M;
  readonly reduceRight: <A, B>(b: B, f: (a: A, b: B) => B) => (fa: HKT<F, A>) => B;
}

Filterable Operations

interface PipeableFilterable<F> extends PipeableCompactable<F> {
  readonly filter: {
    <A, B extends A>(refinement: Refinement<A, B>): (fa: HKT<F, A>) => HKT<F, B>;
    <A>(predicate: Predicate<A>): (fa: HKT<F, A>) => HKT<F, A>;
  };
  readonly filterMap: <A, B>(f: (a: A) => Option<B>) => (fa: HKT<F, A>) => HKT<F, B>;
  readonly partition: {
    <A, B extends A>(refinement: Refinement<A, B>): (fa: HKT<F, A>) => Separated<HKT<F, A>, HKT<F, B>>;
    <A>(predicate: Predicate<A>): (fa: HKT<F, A>) => Separated<HKT<F, A>, HKT<F, A>>;
  };
  readonly partitionMap: <A, RL, RR>(
    f: (a: A) => Either<RL, RR>
  ) => (fa: HKT<F, A>) => Separated<HKT<F, RL>, HKT<F, RR>>;
}

Pipeable Function

Creates pipeable operators from type class instances, enabling the modern functional style for any data type.

/**
 * Creates pipeable operators from a type class instance
 * Automatically detects available operations and generates appropriate pipeable functions
 */
function pipeable<F extends URIS4, I>(
  I: { URI: F } & I
): PipeableChain4<F> & PipeableApply4<F> & PipeableFunctor4<F> & /* ... other interfaces based on I */;

function pipeable<F extends URIS3, I>(
  I: { URI: F } & I
): PipeableChain3<F> & PipeableApply3<F> & PipeableFunctor3<F> & /* ... other interfaces based on I */;

function pipeable<F extends URIS2, I>(
  I: { URI: F } & I
): PipeableChain2<F> & PipeableApply2<F> & PipeableFunctor2<F> & /* ... other interfaces based on I */;

function pipeable<F extends URIS, I>(
  I: { URI: F } & I
): PipeableChain1<F> & PipeableApply1<F> & PipeableFunctor1<F> & /* ... other interfaces based on I */;

Usage Examples:

import { pipeable } from "fp-ts/lib/pipeable";
import { option } from "fp-ts/lib/Option";
import { either } from "fp-ts/lib/Either";
import { array } from "fp-ts/lib/Array";

// Create pipeable operators for Option
const { map, chain, filter } = pipeable(option);

// Create pipeable operators for Either
const { map: mapE, mapLeft, bimap } = pipeable(either);

// Create pipeable operators for Array
const { map: mapA, filter: filterA, fold } = pipeable(array);

// Use in pipelines
pipe(
  some(42),
  map((n: number) => n * 2),
  chain((n: number) => n > 50 ? some(n) : none),
  filter((n: number) => n % 2 === 0)
);

Specialized Pipeable Interfaces

Bifunctor Operations

interface PipeableBifunctor<F> {
  readonly bimap: <L, A, M, B>(f: (l: L) => M, g: (a: A) => B) => (fa: HKT2<F, L, A>) => HKT2<F, M, B>;
  readonly mapLeft: <L, M>(f: (l: L) => M) => <A>(fa: HKT2<F, L, A>) => HKT2<F, M, A>;
}

Contravariant Operations

interface PipeableContravariant<F> {
  readonly contramap: <A, B>(f: (b: B) => A) => (fa: HKT<F, A>) => HKT<F, B>;
}

MonadThrow Operations

interface PipeableMonadThrow<F> {
  readonly fromOption: <E>(onNone: () => E) => <A>(ma: Option<A>) => HKT<F, A>;
  readonly fromEither: <E, A>(ma: Either<E, A>) => HKT<F, A>;
  readonly fromPredicate: {
    <E, A, B extends A>(refinement: Refinement<A, B>, onFalse: (a: A) => E): (a: A) => HKT<F, B>;
    <E, A>(predicate: Predicate<A>, onFalse: (a: A) => E): (a: A) => HKT<F, A>;
  };
  readonly filterOrElse: {
    <E, A, B extends A>(refinement: Refinement<A, B>, onFalse: (a: A) => E): (ma: HKT<F, A>) => HKT<F, B>;
    <E, A>(predicate: Predicate<A>, onFalse: (a: A) => E): (ma: HKT<F, A>) => HKT<F, A>;
  };
}

Type-Level Support

All pipeable interfaces come in multiple variants to support fp-ts's Higher Kinded Types system:

// For HKT (generic)
interface PipeableFunctor<F> { /* ... */ }

// For URIS (single type parameter)
interface PipeableFunctor1<F extends URIS> { /* ... */ }

// For URIS2 (two type parameters)
interface PipeableFunctor2<F extends URIS2> { /* ... */ }

// For URIS2C (two type parameters, first constrained)
interface PipeableFunctor2C<F extends URIS2, L> { /* ... */ }

// For URIS3 (three type parameters)
interface PipeableFunctor3<F extends URIS3> { /* ... */ }

// For URIS4 (four type parameters)
interface PipeableFunctor4<F extends URIS4> { /* ... */ }

Common Patterns

Pipeline Composition

import { pipe } from "fp-ts/lib/pipeable";
import { some, none, map, chain, fold } from "fp-ts/lib/Option";

const processValue = (input: number) => pipe(
  some(input),
  map((n: number) => n * 2),
  chain((n: number) => n > 10 ? some(n) : none),
  fold(
    () => "Value too small",
    (n: number) => `Processed value: ${n}`
  )
);

Error Handling Pipelines

import { pipe } from "fp-ts/lib/pipeable";
import { left, right, map, mapLeft, fold } from "fp-ts/lib/Either";

const parseAndDouble = (input: string) => pipe(
  parseInt(input, 10),
  (n: number) => isNaN(n) ? left("Invalid number") : right(n),
  map((n: number) => n * 2),
  mapLeft((error: string) => `Parse error: ${error}`),
  fold(
    (error: string) => ({ success: false, error }),
    (value: number) => ({ success: true, value })
  )
);

Collection Processing

import { pipe } from "fp-ts/lib/pipeable";
import { map, filter, fold } from "fp-ts/lib/Array";

const processNumbers = (numbers: number[]) => pipe(
  numbers,
  filter((n: number) => n > 0),
  map((n: number) => n * n),
  fold(0, (acc: number, n: number) => acc + n)
);

Types

// Higher Kinded Types support
import { HKT, HKT2, Kind, Kind2, Kind3, Kind4, URIS, URIS2, URIS3, URIS4 } from './HKT';

// Supporting types
import { Predicate, Refinement } from './function';
import { Option } from './Option';
import { Either } from './Either';
import { Separated } from './Compactable';
import { Monoid } from './Monoid';

docs

algebraic.md

array.md

either.md

function.md

index.md

io.md

option.md

pipeable.md

record.md

task-either.md

task.md

type-classes.md

tile.json