/**
 * The `Function` module provides small, pure helpers for defining, composing,
 * adapting, and reusing TypeScript functions. It is the foundation for the
 * data-first and data-last APIs used throughout Effect, and it includes the
 * core pipeline utilities that make those APIs ergonomic.
 *
 * **Mental model**
 *
 * - {@link pipe} starts with a value and passes it through one unary function at
 *   a time
 * - {@link flow} composes unary functions into a reusable function
 * - {@link dual} builds APIs that support both direct calls and `pipe`-friendly
 *   data-last calls
 * - {@link identity}, {@link constant}, and the `const*` helpers model common
 *   identity and thunk patterns without allocating ad hoc callbacks
 * - {@link tupled}, {@link untupled}, {@link flip}, and {@link apply} adapt
 *   call shapes without changing the underlying behavior
 * - Type helpers such as {@link LazyArg}, {@link FunctionN}, {@link satisfies},
 *   and {@link cast} describe or constrain functions at the type level
 *
 * **Common tasks**
 *
 * - Build readable transformation pipelines: {@link pipe}
 * - Create reusable composed functions: {@link flow}, {@link compose}
 * - Define functions callable in both data-first and data-last style: {@link dual}
 * - Return a value unchanged: {@link identity}
 * - Create thunks and common constant functions: {@link constant},
 *   {@link constTrue}, {@link constFalse}, {@link constNull},
 *   {@link constUndefined}, {@link constVoid}
 * - Convert between rest-argument and tuple-argument functions: {@link tupled},
 *   {@link untupled}
 * - Express impossible branches: {@link absurd}
 * - Cache results for object keys: {@link memoize}
 *
 * **Gotchas**
 *
 * - Functions passed to {@link pipe} and {@link flow} are applied left-to-right
 *   and should be unary at each step
 * - {@link dual} uses either an arity or a predicate to decide whether a call is
 *   data-first or data-last; use a predicate when optional arguments make arity
 *   ambiguous
 * - {@link cast} changes only the static TypeScript type and performs no runtime
 *   validation
 * - {@link memoize} is intended for object keys and stores cached values in a
 *   `WeakMap`
 *
 * @since 2.0.0
 */
import type { TypeLambda } from "./HKT.ts";
/**
 * Type lambda for function types, used for higher-kinded type operations.
 *
 * **When to use**
 *
 * Use to represent unary function types in higher-kinded type operations.
 *
 * **Example** (Creating a function type with a type lambda)
 *
 * ```ts
 * import type { Function, HKT } from "effect"
 *
 * // Create a function type using the type lambda
 * type StringToNumber = HKT.Kind<Function.FunctionTypeLambda, string, never, never, number>
 * // Equivalent to: (a: string) => number
 * ```
 *
 * @category type lambdas
 * @since 2.0.0
 */
export interface FunctionTypeLambda extends TypeLambda {
    readonly type: (a: this["In"]) => this["Target"];
}
/**
 * Creates a function that can be called in data-first style or data-last
 * (`pipe`-friendly) style.
 *
 * **When to use**
 *
 * Use to expose one implementation through both direct and `pipe`-friendly
 * call styles.
 *
 * **Details**
 *
 * Pass either the arity of the uncurried function or a predicate that decides
 * whether the current call is data-first. Arity is the common case. Use a
 * predicate when optional arguments make arity ambiguous.
 *
 * **Example** (Using arity to determine data-first or data-last style)
 *
 * ```ts
 * import { Function, pipe } from "effect"
 *
 * const sum = Function.dual<
 *   (that: number) => (self: number) => number,
 *   (self: number, that: number) => number
 * >(2, (self, that) => self + that)
 *
 * console.log(sum(2, 3)) // 5
 * console.log(pipe(2, sum(3))) // 5
 * ```
 *
 * **Example** (Using call signatures to define the overloads)
 *
 * ```ts
 * import { Function, pipe } from "effect"
 *
 * const sum: {
 *   (that: number): (self: number) => number
 *   (self: number, that: number): number
 * } = Function.dual(2, (self: number, that: number): number => self + that)
 *
 * console.log(sum(2, 3)) // 5
 * console.log(pipe(2, sum(3))) // 5
 * ```
 *
 * **Example** (Using a predicate to determine data-first or data-last style)
 *
 * ```ts
 * import { Function, pipe } from "effect"
 *
 * const sum = Function.dual<
 *   (that: number) => (self: number) => number,
 *   (self: number, that: number) => number
 * >(
 *   (args) => args.length === 2,
 *   (self, that) => self + that
 * )
 *
 * console.log(sum(2, 3)) // 5
 * console.log(pipe(2, sum(3))) // 5
 * ```
 *
 * @category combinators
 * @since 2.0.0
 */
export declare const dual: {
    /**
     * Creates a function that can be called in data-first style or data-last
     * (`pipe`-friendly) style.
     *
     * **When to use**
     *
     * Use to expose one implementation through both direct and `pipe`-friendly
     * call styles.
     *
     * **Details**
     *
     * Pass either the arity of the uncurried function or a predicate that decides
     * whether the current call is data-first. Arity is the common case. Use a
     * predicate when optional arguments make arity ambiguous.
     *
     * **Example** (Using arity to determine data-first or data-last style)
     *
     * ```ts
     * import { Function, pipe } from "effect"
     *
     * const sum = Function.dual<
     *   (that: number) => (self: number) => number,
     *   (self: number, that: number) => number
     * >(2, (self, that) => self + that)
     *
     * console.log(sum(2, 3)) // 5
     * console.log(pipe(2, sum(3))) // 5
     * ```
     *
     * **Example** (Using call signatures to define the overloads)
     *
     * ```ts
     * import { Function, pipe } from "effect"
     *
     * const sum: {
     *   (that: number): (self: number) => number
     *   (self: number, that: number): number
     * } = Function.dual(2, (self: number, that: number): number => self + that)
     *
     * console.log(sum(2, 3)) // 5
     * console.log(pipe(2, sum(3))) // 5
     * ```
     *
     * **Example** (Using a predicate to determine data-first or data-last style)
     *
     * ```ts
     * import { Function, pipe } from "effect"
     *
     * const sum = Function.dual<
     *   (that: number) => (self: number) => number,
     *   (self: number, that: number) => number
     * >(
     *   (args) => args.length === 2,
     *   (self, that) => self + that
     * )
     *
     * console.log(sum(2, 3)) // 5
     * console.log(pipe(2, sum(3))) // 5
     * ```
     *
     * @category combinators
     * @since 2.0.0
     */
    <DataLast extends (...args: Array<any>) => any, DataFirst extends (...args: Array<any>) => any>(arity: Parameters<DataFirst>["length"], body: DataFirst): DataLast & DataFirst;
    /**
     * Creates a function that can be called in data-first style or data-last
     * (`pipe`-friendly) style.
     *
     * **When to use**
     *
     * Use to expose one implementation through both direct and `pipe`-friendly
     * call styles.
     *
     * **Details**
     *
     * Pass either the arity of the uncurried function or a predicate that decides
     * whether the current call is data-first. Arity is the common case. Use a
     * predicate when optional arguments make arity ambiguous.
     *
     * **Example** (Using arity to determine data-first or data-last style)
     *
     * ```ts
     * import { Function, pipe } from "effect"
     *
     * const sum = Function.dual<
     *   (that: number) => (self: number) => number,
     *   (self: number, that: number) => number
     * >(2, (self, that) => self + that)
     *
     * console.log(sum(2, 3)) // 5
     * console.log(pipe(2, sum(3))) // 5
     * ```
     *
     * **Example** (Using call signatures to define the overloads)
     *
     * ```ts
     * import { Function, pipe } from "effect"
     *
     * const sum: {
     *   (that: number): (self: number) => number
     *   (self: number, that: number): number
     * } = Function.dual(2, (self: number, that: number): number => self + that)
     *
     * console.log(sum(2, 3)) // 5
     * console.log(pipe(2, sum(3))) // 5
     * ```
     *
     * **Example** (Using a predicate to determine data-first or data-last style)
     *
     * ```ts
     * import { Function, pipe } from "effect"
     *
     * const sum = Function.dual<
     *   (that: number) => (self: number) => number,
     *   (self: number, that: number) => number
     * >(
     *   (args) => args.length === 2,
     *   (self, that) => self + that
     * )
     *
     * console.log(sum(2, 3)) // 5
     * console.log(pipe(2, sum(3))) // 5
     * ```
     *
     * @category combinators
     * @since 2.0.0
     */
    <DataLast extends (...args: Array<any>) => any, DataFirst extends (...args: Array<any>) => any>(isDataFirst: (args: IArguments) => boolean, body: DataFirst): DataLast & DataFirst;
};
/**
 * Applies a function to a given value.
 *
 * **When to use**
 *
 * Use to pass a fixed value into a unary function, especially when the function
 * is the value flowing through `pipe`.
 *
 * **Details**
 *
 * `apply(a)(f)` is equivalent to `f(a)`.
 *
 * **Example** (Applying an argument to a function)
 *
 * ```ts
 * import { Function, pipe, String } from "effect"
 * import * as assert from "node:assert"
 *
 * assert.deepStrictEqual(pipe(String.length, Function.apply("hello")), 5)
 * ```
 *
 * @see {@link pipe} for building left-to-right pipelines
 *
 * @category combinators
 * @since 2.0.0
 */
export declare const apply: <A>(a: A) => <B>(self: (a: A) => B) => B;
/**
 * A zero-argument function that produces a value when invoked.
 *
 * **When to use**
 *
 * Use to type a lazy value provider that should not run until called.
 *
 * **Example** (Creating a lazy argument)
 *
 * ```ts
 * import { Function } from "effect"
 *
 * const constNull: Function.LazyArg<null> = Function.constant(null)
 * ```
 *
 * @category models
 * @since 2.0.0
 */
export type LazyArg<A> = () => A;
/**
 * Represents a function with multiple arguments.
 *
 * **When to use**
 *
 * Use to describe a function whose argument list is represented as a tuple
 * type.
 *
 * **Example** (Typing a variadic function)
 *
 * ```ts
 * import type { Function } from "effect"
 * import * as assert from "node:assert"
 *
 * const sum: Function.FunctionN<[number, number], number> = (a, b) => a + b
 * assert.deepStrictEqual(sum(2, 3), 5)
 * ```
 *
 * @category models
 * @since 2.0.0
 */
export type FunctionN<A extends ReadonlyArray<unknown>, B> = (...args: A) => B;
/**
 * Returns its input argument unchanged.
 *
 * **When to use**
 *
 * Use to return a value unchanged where a function is required.
 *
 * **Example** (Returning the same value)
 *
 * ```ts
 * import { identity } from "effect"
 * import * as assert from "node:assert"
 *
 * assert.deepStrictEqual(identity(5), 5)
 * ```
 *
 * @category combinators
 * @since 2.0.0
 */
export declare const identity: <A>(a: A) => A;
/**
 * Ensures that the type of an expression matches some type,
 * without changing the resulting type of that expression.
 *
 * **When to use**
 *
 * Use to check assignability while preserving the expression's precise inferred
 * type.
 *
 * **Example** (Checking an expression against a type)
 *
 * ```ts
 * import { Function } from "effect"
 * import * as assert from "node:assert"
 *
 * const test1 = Function.satisfies<number>()(5 as const)
 * // ^? const test: 5
 * // @ts-expect-error
 * const test2 = Function.satisfies<string>()(5)
 * // ^? Argument of type 'number' is not assignable to parameter of type 'string'
 *
 * assert.deepStrictEqual(Function.satisfies<number>()(5), 5)
 * ```
 *
 * @see {@link cast} for changing only the static TypeScript type
 *
 * @category utility types
 * @since 2.0.0
 */
export declare const satisfies: <A>() => <B extends A>(b: B) => B;
/**
 * Returns the input value with a different static type.
 *
 * **When to use**
 *
 * Use when you need an explicit type-level cast and accept that the value is
 * returned unchanged at runtime.
 *
 * **Gotchas**
 *
 * This is a type-level cast only; it performs no runtime validation or
 * conversion.
 *
 * @see {@link satisfies} for checking assignability without changing the resulting type
 *
 * @category utility types
 * @since 4.0.0
 */
export declare const cast: <A, B>(a: A) => B;
/**
 * Creates a zero-argument function that always returns the provided value.
 *
 * **When to use**
 *
 * Use when an API expects a thunk or callback and every invocation
 * should return the same value.
 *
 * **Example** (Creating a constant thunk)
 *
 * ```ts
 * import { Function } from "effect"
 * import * as assert from "node:assert"
 *
 * const constNull = Function.constant(null)
 *
 * assert.deepStrictEqual(constNull(), null)
 * assert.deepStrictEqual(constNull(), null)
 * ```
 *
 * @category constructors
 * @since 2.0.0
 */
export declare const constant: <A>(value: A) => LazyArg<A>;
/**
 * Returns `true` when called.
 *
 * **When to use**
 *
 * Use when an API expects a thunk and every invocation should return `true`.
 *
 * **Example** (Returning true from a thunk)
 *
 * ```ts
 * import { Function } from "effect"
 * import * as assert from "node:assert"
 *
 * assert.deepStrictEqual(Function.constTrue(), true)
 * ```
 *
 * @category constants
 * @since 2.0.0
 */
export declare const constTrue: LazyArg<boolean>;
/**
 * Returns `false` when called.
 *
 * **When to use**
 *
 * Use when an API expects a thunk and every invocation should return `false`.
 *
 * **Example** (Returning false from a thunk)
 *
 * ```ts
 * import { Function } from "effect"
 * import * as assert from "node:assert"
 *
 * assert.deepStrictEqual(Function.constFalse(), false)
 * ```
 *
 * @category constants
 * @since 2.0.0
 */
export declare const constFalse: LazyArg<boolean>;
/**
 * Returns `null` when called.
 *
 * **When to use**
 *
 * Use when an API expects a thunk and every invocation should return `null`.
 *
 * **Example** (Returning null from a thunk)
 *
 * ```ts
 * import { Function } from "effect"
 * import * as assert from "node:assert"
 *
 * assert.deepStrictEqual(Function.constNull(), null)
 * ```
 *
 * @category constants
 * @since 2.0.0
 */
export declare const constNull: LazyArg<null>;
/**
 * Returns `undefined` when called.
 *
 * **When to use**
 *
 * Use when an API expects a thunk and every invocation should return
 * `undefined`.
 *
 * **Example** (Returning undefined from a thunk)
 *
 * ```ts
 * import { Function } from "effect"
 * import * as assert from "node:assert"
 *
 * assert.deepStrictEqual(Function.constUndefined(), undefined)
 * ```
 *
 * @category constants
 * @since 2.0.0
 */
export declare const constUndefined: LazyArg<undefined>;
/**
 * Returns no meaningful value when called.
 *
 * **When to use**
 *
 * Use when an API expects a thunk used only for its call effect and not for a
 * meaningful return value.
 *
 * **Example** (Returning void from a thunk)
 *
 * ```ts
 * import { Function } from "effect"
 * import * as assert from "node:assert"
 *
 * assert.deepStrictEqual(Function.constVoid(), undefined)
 * ```
 *
 * @category constants
 * @since 2.0.0
 */
export declare const constVoid: LazyArg<void>;
/**
 * Reverses the order of arguments for a curried function.
 *
 * **When to use**
 *
 * Use to adapt a curried function when its argument groups need to be supplied
 * in the opposite order.
 *
 * **Example** (Flipping curried arguments)
 *
 * ```ts
 * import { Function } from "effect"
 * import * as assert from "node:assert"
 *
 * const f = (a: number) => (b: string) => a - b.length
 *
 * assert.deepStrictEqual(Function.flip(f)("aaa")(2), -1)
 * ```
 *
 * @category combinators
 * @since 2.0.0
 */
export declare const flip: <A extends Array<unknown>, B extends Array<unknown>, C>(f: (...a: A) => (...b: B) => C) => (...b: B) => (...a: A) => C;
/**
 * Composes two functions, `ab` and `bc` into a single function that takes in an argument `a` of type `A` and returns a result of type `C`.
 * The result is obtained by first applying the `ab` function to `a` and then applying the `bc` function to the result of `ab`.
 *
 * **When to use**
 *
 * Use to compose exactly two unary functions into a reusable unary function.
 *
 * **Example** (Composing two functions)
 *
 * ```ts
 * import { Function } from "effect"
 * import * as assert from "node:assert"
 *
 * const increment = (n: number) => n + 1
 * const square = (n: number) => n * n
 *
 * assert.strictEqual(Function.compose(increment, square)(2), 9)
 * ```
 *
 * @see {@link flow} for composing a left-to-right sequence of functions
 * @see {@link pipe} for applying a value through a left-to-right sequence immediately
 *
 * @category combinators
 * @since 2.0.0
 */
export declare const compose: {
    /**
     * Composes two functions, `ab` and `bc` into a single function that takes in an argument `a` of type `A` and returns a result of type `C`.
     * The result is obtained by first applying the `ab` function to `a` and then applying the `bc` function to the result of `ab`.
     *
     * **When to use**
     *
     * Use to compose exactly two unary functions into a reusable unary function.
     *
     * **Example** (Composing two functions)
     *
     * ```ts
     * import { Function } from "effect"
     * import * as assert from "node:assert"
     *
     * const increment = (n: number) => n + 1
     * const square = (n: number) => n * n
     *
     * assert.strictEqual(Function.compose(increment, square)(2), 9)
     * ```
     *
     * @see {@link flow} for composing a left-to-right sequence of functions
     * @see {@link pipe} for applying a value through a left-to-right sequence immediately
     *
     * @category combinators
     * @since 2.0.0
     */
    <B, C>(bc: (b: B) => C): <A>(self: (a: A) => B) => (a: A) => C;
    /**
     * Composes two functions, `ab` and `bc` into a single function that takes in an argument `a` of type `A` and returns a result of type `C`.
     * The result is obtained by first applying the `ab` function to `a` and then applying the `bc` function to the result of `ab`.
     *
     * **When to use**
     *
     * Use to compose exactly two unary functions into a reusable unary function.
     *
     * **Example** (Composing two functions)
     *
     * ```ts
     * import { Function } from "effect"
     * import * as assert from "node:assert"
     *
     * const increment = (n: number) => n + 1
     * const square = (n: number) => n * n
     *
     * assert.strictEqual(Function.compose(increment, square)(2), 9)
     * ```
     *
     * @see {@link flow} for composing a left-to-right sequence of functions
     * @see {@link pipe} for applying a value through a left-to-right sequence immediately
     *
     * @category combinators
     * @since 2.0.0
     */
    <A, B, C>(self: (a: A) => B, bc: (b: B) => C): (a: A) => C;
};
/**
 * Marks an impossible branch by accepting a `never` value and returning any
 * type.
 *
 * **When to use**
 *
 * Use when exhaustive checks prove a branch cannot be reached, but
 * TypeScript still needs a return value.
 *
 * **Gotchas**
 *
 * Calling `absurd` throws, because a value of type `never` should be
 * impossible at runtime.
 *
 * **Example** (Handling impossible values)
 *
 * ```ts
 * import { absurd } from "effect"
 *
 * const handleNever = (value: never) => {
 *   return absurd(value) // This will throw an error if called
 * }
 * ```
 *
 * @category utility types
 * @since 2.0.0
 */
export declare const absurd: <A>(_: never) => A;
/**
 * Creates a tupled version of this function: instead of `n` arguments, it accepts a single tuple argument.
 *
 * **When to use**
 *
 * Use to adapt a multi-argument function so it accepts one tuple argument.
 *
 * **Example** (Converting arguments to a tuple)
 *
 * ```ts
 * import { Function } from "effect"
 * import * as assert from "node:assert"
 *
 * const sumTupled = Function.tupled((x: number, y: number): number => x + y)
 *
 * assert.deepStrictEqual(sumTupled([1, 2]), 3)
 * ```
 *
 * @see {@link untupled} for adapting a tuple-argument function back to multiple arguments
 *
 * @category combinators
 * @since 2.0.0
 */
export declare const tupled: <A extends ReadonlyArray<unknown>, B>(f: (...a: A) => B) => (a: A) => B;
/**
 * Converts a tupled function back to an uncurried function.
 *
 * **When to use**
 *
 * Use to adapt a tuple-argument function so it accepts multiple arguments.
 *
 * **Example** (Converting a tuple to arguments)
 *
 * ```ts
 * import { Function } from "effect"
 * import * as assert from "node:assert"
 *
 * const getFirst = Function.untupled(<A, B>(tuple: [A, B]): A => tuple[0])
 *
 * assert.deepStrictEqual(getFirst(1, 2), 1)
 * ```
 *
 * @see {@link tupled} for adapting a multi-argument function to one tuple argument
 *
 * @category combinators
 * @since 2.0.0
 */
export declare const untupled: <A extends ReadonlyArray<unknown>, B>(f: (a: A) => B) => (...a: A) => B;
/**
 * Pipes the value of an expression through a left-to-right sequence of
 * functions.
 *
 * **When to use**
 *
 * Use when you use `pipe` with data-last functions to build readable transformation
 * pipelines and to write method-style chains as ordinary function calls.
 *
 * **Details**
 *
 * `pipe` takes an initial value, passes it to the first function, then passes
 * each result to the next function in order. The final function result is
 * returned.
 *
 * **Gotchas**
 *
 * Each function passed after the initial value must accept a single argument,
 * because `pipe` calls each step with only the previous result.
 *
 * **Example** (Using pipeline syntax)
 *
 * In this example, `1` is passed to the first function, and each result becomes
 * the input for the next function.
 *
 * ```ts
 * import { pipe } from "effect"
 *
 * const result = pipe(
 *   1,
 *   (n) => n + 1,
 *   (n) => n * 2,
 *   (n) => `result: ${n}`
 * )
 *
 * console.log(result) // "result: 4"
 * ```
 *
 * **Example** (Chaining methods before conversion)
 *
 * ```ts
 * const numbers = [1, 2, 3, 4]
 * const double = (n: number) => n * 2
 * const greaterThanFour = (n: number) => n > 4
 *
 * const result = numbers.map(double).filter(greaterThanFour)
 *
 * console.log(result) // [6, 8]
 * ```
 *
 * **Example** (Rewriting method chains with pipe)
 *
 * The same transformation can be written with data-last functions.
 *
 * ```ts
 * import { Array, pipe } from "effect"
 *
 * const numbers = [1, 2, 3, 4]
 * const double = (n: number) => n * 2
 * const greaterThanFour = (n: number) => n > 4
 *
 * const result = pipe(
 *   numbers,
 *   Array.map(double),
 *   Array.filter(greaterThanFour)
 * )
 *
 * console.log(result) // [6, 8]
 * ```
 *
 * **Example** (Chaining arithmetic operations)
 *
 * ```ts
 * import { pipe } from "effect"
 *
 * // Define simple arithmetic operations
 * const increment = (x: number) => x + 1
 * const double = (x: number) => x * 2
 * const subtractTen = (x: number) => x - 10
 *
 * // Sequentially apply these operations using `pipe`
 * const result = pipe(5, increment, double, subtractTen)
 *
 * console.log(result)
 * // Output: 2
 * ```
 *
 * **Example** (Building a simple transformation pipeline)
 *
 * ```ts
 * import { pipe } from "effect"
 *
 * // Simple transformation pipeline
 * const result = pipe(
 *   5,
 *   (x) => x * 2, // 10
 *   (x) => x + 1, // 11
 *   (x) => x.toString() // "11"
 * )
 *
 * console.log(result) // "11"
 * ```
 *
 * @category combinators
 * @since 2.0.0
 */
export declare function pipe<A>(a: A): A;
export declare function pipe<A, B = never>(a: A, ab: (a: A) => B): B;
export declare function pipe<A, B = never, C = never>(a: A, ab: (a: A) => B, bc: (b: B) => C): C;
export declare function pipe<A, B = never, C = never, D = never>(a: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D): D;
export declare function pipe<A, B = never, C = never, D = never, E = never>(a: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E): E;
export declare function pipe<A, B = never, C = never, D = never, E = never, F = never>(a: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F): F;
export declare function pipe<A, B = never, C = never, D = never, E = never, F = never, G = never>(a: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G): G;
export declare function pipe<A, B = never, C = never, D = never, E = never, F = never, G = never, H = never>(a: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H): H;
export declare function pipe<A, B = never, C = never, D = never, E = never, F = never, G = never, H = never, I = never>(a: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H, hi: (h: H) => I): I;
export declare function pipe<A, B = never, C = never, D = never, E = never, F = never, G = never, H = never, I = never, J = never>(a: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H, hi: (h: H) => I, ij: (i: I) => J): J;
export declare function pipe<A, B = never, C = never, D = never, E = never, F = never, G = never, H = never, I = never, J = never, K = never>(a: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H, hi: (h: H) => I, ij: (i: I) => J, jk: (j: J) => K): K;
export declare function pipe<A, B = never, C = never, D = never, E = never, F = never, G = never, H = never, I = never, J = never, K = never, L = never>(a: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H, hi: (h: H) => I, ij: (i: I) => J, jk: (j: J) => K, kl: (k: K) => L): L;
export declare function pipe<A, B = never, C = never, D = never, E = never, F = never, G = never, H = never, I = never, J = never, K = never, L = never, M = never>(a: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H, hi: (h: H) => I, ij: (i: I) => J, jk: (j: J) => K, kl: (k: K) => L, lm: (l: L) => M): M;
export declare function pipe<A, B = never, C = never, D = never, E = never, F = never, G = never, H = never, I = never, J = never, K = never, L = never, M = never, N = never>(a: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H, hi: (h: H) => I, ij: (i: I) => J, jk: (j: J) => K, kl: (k: K) => L, lm: (l: L) => M, mn: (m: M) => N): N;
export declare function pipe<A, B = never, C = never, D = never, E = never, F = never, G = never, H = never, I = never, J = never, K = never, L = never, M = never, N = never, O = never>(a: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H, hi: (h: H) => I, ij: (i: I) => J, jk: (j: J) => K, kl: (k: K) => L, lm: (l: L) => M, mn: (m: M) => N, no: (n: N) => O): O;
export declare function pipe<A, B = never, C = never, D = never, E = never, F = never, G = never, H = never, I = never, J = never, K = never, L = never, M = never, N = never, O = never, P = never>(a: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H, hi: (h: H) => I, ij: (i: I) => J, jk: (j: J) => K, kl: (k: K) => L, lm: (l: L) => M, mn: (m: M) => N, no: (n: N) => O, op: (o: O) => P): P;
export declare function pipe<A, B = never, C = never, D = never, E = never, F = never, G = never, H = never, I = never, J = never, K = never, L = never, M = never, N = never, O = never, P = never, Q = never>(a: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H, hi: (h: H) => I, ij: (i: I) => J, jk: (j: J) => K, kl: (k: K) => L, lm: (l: L) => M, mn: (m: M) => N, no: (n: N) => O, op: (o: O) => P, pq: (p: P) => Q): Q;
export declare function pipe<A, B = never, C = never, D = never, E = never, F = never, G = never, H = never, I = never, J = never, K = never, L = never, M = never, N = never, O = never, P = never, Q = never, R = never>(a: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H, hi: (h: H) => I, ij: (i: I) => J, jk: (j: J) => K, kl: (k: K) => L, lm: (l: L) => M, mn: (m: M) => N, no: (n: N) => O, op: (o: O) => P, pq: (p: P) => Q, qr: (q: Q) => R): R;
export declare function pipe<A, B = never, C = never, D = never, E = never, F = never, G = never, H = never, I = never, J = never, K = never, L = never, M = never, N = never, O = never, P = never, Q = never, R = never, S = never>(a: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H, hi: (h: H) => I, ij: (i: I) => J, jk: (j: J) => K, kl: (k: K) => L, lm: (l: L) => M, mn: (m: M) => N, no: (n: N) => O, op: (o: O) => P, pq: (p: P) => Q, qr: (q: Q) => R, rs: (r: R) => S): S;
export declare function pipe<A, B = never, C = never, D = never, E = never, F = never, G = never, H = never, I = never, J = never, K = never, L = never, M = never, N = never, O = never, P = never, Q = never, R = never, S = never, T = never>(a: A, ab: (a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H, hi: (h: H) => I, ij: (i: I) => J, jk: (j: J) => K, kl: (k: K) => L, lm: (l: L) => M, mn: (m: M) => N, no: (n: N) => O, op: (o: O) => P, pq: (p: P) => Q, qr: (q: Q) => R, rs: (r: R) => S, st: (s: S) => T): T;
/**
 * Performs left-to-right function composition.
 *
 * **When to use**
 *
 * Use to build a reusable function from a left-to-right sequence of
 * transformations.
 *
 * **Details**
 *
 * The first function may have any arity. Every following function must be
 * unary.
 *
 * **Example** (Composing functions left to right)
 *
 * ```ts
 * import { flow } from "effect"
 * import * as assert from "node:assert"
 *
 * const len = (s: string): number => s.length
 * const double = (n: number): number => n * 2
 *
 * const f = flow(len, double)
 *
 * assert.strictEqual(f("aaa"), 6)
 * ```
 *
 * @see {@link pipe} for applying a value through a left-to-right sequence immediately
 * @see {@link compose} for composing exactly two functions
 *
 * @category combinators
 * @since 2.0.0
 */
export declare function flow<A extends ReadonlyArray<unknown>, B = never>(ab: (...a: A) => B): (...a: A) => B;
export declare function flow<A extends ReadonlyArray<unknown>, B = never, C = never>(ab: (...a: A) => B, bc: (b: B) => C): (...a: A) => C;
export declare function flow<A extends ReadonlyArray<unknown>, B = never, C = never, D = never>(ab: (...a: A) => B, bc: (b: B) => C, cd: (c: C) => D): (...a: A) => D;
export declare function flow<A extends ReadonlyArray<unknown>, B = never, C = never, D = never, E = never>(ab: (...a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E): (...a: A) => E;
export declare function flow<A extends ReadonlyArray<unknown>, B = never, C = never, D = never, E = never, F = never>(ab: (...a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F): (...a: A) => F;
export declare function flow<A extends ReadonlyArray<unknown>, B = never, C = never, D = never, E = never, F = never, G = never>(ab: (...a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G): (...a: A) => G;
export declare function flow<A extends ReadonlyArray<unknown>, B = never, C = never, D = never, E = never, F = never, G = never, H = never>(ab: (...a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H): (...a: A) => H;
export declare function flow<A extends ReadonlyArray<unknown>, B = never, C = never, D = never, E = never, F = never, G = never, H = never, I = never>(ab: (...a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H, hi: (h: H) => I): (...a: A) => I;
export declare function flow<A extends ReadonlyArray<unknown>, B = never, C = never, D = never, E = never, F = never, G = never, H = never, I = never, J = never>(ab: (...a: A) => B, bc: (b: B) => C, cd: (c: C) => D, de: (d: D) => E, ef: (e: E) => F, fg: (f: F) => G, gh: (g: G) => H, hi: (h: H) => I, ij: (i: I) => J): (...a: A) => J;
/**
 * Creates a compile-time placeholder for a value of any type.
 *
 * **When to use**
 *
 * Use as a temporary typed placeholder while developing incomplete code.
 *
 * **Gotchas**
 *
 * `hole` is intended for temporary development use. If the placeholder is
 * evaluated at runtime, it throws.
 *
 * **Example** (Creating a development placeholder)
 *
 * ```ts
 * import { hole } from "effect"
 *
 * // Intentionally not called: `hole` throws if the placeholder is evaluated.
 * const buildUser = (id: number): { readonly id: number; readonly name: string } => ({
 *   id,
 *   name: hole<string>()
 * })
 *
 * console.log(typeof buildUser) // "function"
 * ```
 *
 * @category utility types
 * @since 2.0.0
 */
export declare const hole: <T>() => T;
/**
 * Returns the second argument and discards the first. The SK combinator is
 * a fundamental combinator in the lambda calculus and the SKI combinator
 * calculus.
 *
 * **When to use**
 *
 * Use to discard the first argument and return the second argument.
 *
 * **Example** (Discarding the first argument)
 *
 * ```ts
 * import { Function } from "effect"
 * import * as assert from "node:assert"
 *
 * assert.deepStrictEqual(Function.SK(0, "hello"), "hello")
 * ```
 *
 * @category combinators
 * @since 2.0.0
 */
export declare const SK: <A, B>(_: A, b: B) => B;
/**
 * Creates a memoized function whose input is an object, caching results by
 * object identity.
 *
 * **When to use**
 *
 * Use to reuse the result of a synchronous computation whose output is stable
 * for a given object reference.
 *
 * **Details**
 *
 * Each memoized wrapper owns a private `WeakMap` keyed by object identity.
 * Cached `undefined` results are still returned because the cache is checked
 * with `WeakMap.has`.
 *
 * **Gotchas**
 *
 * Structurally equal objects do not share cache entries. If the same object is
 * mutated after its first call, later calls still return the cached result for
 * that reference.
 *
 * @category caching
 * @since 4.0.0
 */
export declare function memoize<A extends object, O>(f: (a: A) => O): (ast: A) => O;
//# sourceMappingURL=Function.d.ts.map