or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

algebraic.mdarray.mdeither.mdfunction.mdindex.mdio.mdoption.mdpipeable.mdrecord.mdtask-either.mdtask.mdtype-classes.md
tile.json

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';