Hyperlinkv0.8.0-beta.28

Predicate

Predicate.composeconsteffect/Predicate.ts:1411
<A, B extends A, C extends B>(bc: Refinement<B, C>): (
  ab: Refinement<A, B>
) => Refinement<A, C>
<A, B extends A>(bc: Predicate<NoInfer<B>>): (
  ab: Refinement<A, B>
) => Refinement<A, B>
<A, B extends A, C extends B>(
  ab: Refinement<A, B>,
  bc: Refinement<B, C>
): Refinement<A, C>
<A, B extends A>(
  ab: Refinement<A, B>,
  bc: Predicate<NoInfer<B>>
): Refinement<A, B>

Composes two predicates or refinements into one.

When to use

Use when you want to compose two Predicate checks in sequence, especially when chaining refinements for progressive narrowing.

Details

For refinements, the output type is narrowed by both checks. Evaluation short-circuits on the first false.

Example (Composing refinements)

import { Predicate } from "effect"

const isNumber: Predicate.Refinement<unknown, number> = (u): u is number => typeof u === "number"
const isInteger: Predicate.Refinement<number, number> = (n): n is number => Number.isInteger(n)

const isIntegerNumber = Predicate.compose(isNumber, isInteger)

console.log(isIntegerNumber(1))
combinatorsandRefinement
export const compose: {
  <A, B extends A, C extends B>(bc: Refinement<B, C>): (ab: Refinement<A, B>) => Refinement<A, C>
  <A, B extends A>(bc: Predicate<NoInfer<B>>): (ab: Refinement<A, B>) => Refinement<A, B>
  <A, B extends A, C extends B>(ab: Refinement<A, B>, bc: Refinement<B, C>): Refinement<A, C>
  <A, B extends A>(ab: Refinement<A, B>, bc: Predicate<NoInfer<B>>): Refinement<A, B>
} = dual(
  2,
  <A, B extends A, C extends B>(ab: Refinement<A, B>, bc: Refinement<B, C>): Refinement<A, C> => (a): a is C =>
    ab(a) && bc(a)
)