<L extends Lambda>(lambda: L): <const T extends ReadonlyArray<unknown>>(
self: T
) => { [K in keyof T]: Apply<L, T[K]> }
<const T extends ReadonlyArray<unknown>, L extends Lambda>(
self: T,
lambda: L
): { [K in keyof T]: Apply<L, T[K]> }Applies a Struct.Lambda transformation to every element in a tuple.
When to use
Use when you want to apply the same transformation to every tuple element.
Details
The lambda lets the compiler track the output type for each element.
Gotchas
The lambda must be created with Struct.lambda; a plain function will not
type-check.
Example (Wrapping every element in an array)
import { pipe, Struct, Tuple } from "effect"
interface AsArray extends Struct.Lambda {
<A>(self: A): Array<A>
readonly "~lambda.out": Array<this["~lambda.in"]>
}
const asArray = Struct.lambda<AsArray>((a) => [a])
const result = pipe(Tuple.make(1, "hello", true), Tuple.map(asArray))
console.log(result) // [[1], ["hello"], [true]]export const const map: {
<L extends Lambda>(lambda: L): <
T extends ReadonlyArray<unknown>
>(
self: T
) => {
[K in keyof T]: Apply<L, T[K]>
}
<
T extends ReadonlyArray<unknown>,
L extends Lambda
>(
self: T,
lambda: L
): {
[K in keyof T]: Apply<L, T[K]>
}
}
Applies a Struct.Lambda transformation to every element in a tuple.
When to use
Use when you want to apply the same transformation to every tuple element.
Details
The lambda lets the compiler track the output type for each element.
Gotchas
The lambda must be created with Struct.lambda; a plain function will not
type-check.
Example (Wrapping every element in an array)
import { pipe, Struct, Tuple } from "effect"
interface AsArray extends Struct.Lambda {
<A>(self: A): Array<A>
readonly "~lambda.out": Array<this["~lambda.in"]>
}
const asArray = Struct.lambda<AsArray>((a) => [a])
const result = pipe(Tuple.make(1, "hello", true), Tuple.map(asArray))
console.log(result) // [[1], ["hello"], [true]]
map: {
<function (type parameter) L in <L extends Lambda>(lambda: L): <const T extends ReadonlyArray<unknown>>(self: T) => { [K in keyof T]: Apply<L, T[K]>; }L extends Lambda>(
lambda: L extends Lambdalambda: function (type parameter) L in <L extends Lambda>(lambda: L): <const T extends ReadonlyArray<unknown>>(self: T) => { [K in keyof T]: Apply<L, T[K]>; }L
): <const function (type parameter) T in <const T extends ReadonlyArray<unknown>>(self: T): { [K in keyof T]: Apply<L, T[K]>; }T extends interface ReadonlyArray<T>ReadonlyArray<unknown>>(
self: const T extends ReadonlyArray<unknown>self: function (type parameter) T in <const T extends ReadonlyArray<unknown>>(self: T): { [K in keyof T]: Apply<L, T[K]>; }T
) => { [function (type parameter) KK in keyof function (type parameter) T in <const T extends ReadonlyArray<unknown>>(self: T): { [K in keyof T]: Apply<L, T[K]>; }T]: type Apply<L extends Lambda, V> = (L & {
readonly "~lambda.in": V;
})["~lambda.out"]
Applies a
Lambda
type-level function to a value type V, producing
the output type.
When to use
Use when you need to compute what type a Lambda would produce for a
given input.
Details
This works by intersecting the Lambda with { "~lambda.in": V } and reading
"~lambda.out".
Example (Computing the output type of a lambda)
import type { Struct } from "effect"
interface ToString extends Struct.Lambda {
readonly "~lambda.out": string
}
// Result is `string`
type Result = Struct.Apply<ToString, number>
Apply<function (type parameter) L in <L extends Lambda>(lambda: L): <const T extends ReadonlyArray<unknown>>(self: T) => { [K in keyof T]: Apply<L, T[K]>; }L, function (type parameter) T in <const T extends ReadonlyArray<unknown>>(self: T): { [K in keyof T]: Apply<L, T[K]>; }T[function (type parameter) KK]> }
<const function (type parameter) T in <const T extends ReadonlyArray<unknown>, L extends Lambda>(self: T, lambda: L): { [K in keyof T]: Apply<L, T[K]>; }T extends interface ReadonlyArray<T>ReadonlyArray<unknown>, function (type parameter) L in <const T extends ReadonlyArray<unknown>, L extends Lambda>(self: T, lambda: L): { [K in keyof T]: Apply<L, T[K]>; }L extends Lambda>(
self: const T extends ReadonlyArray<unknown>self: function (type parameter) T in <const T extends ReadonlyArray<unknown>, L extends Lambda>(self: T, lambda: L): { [K in keyof T]: Apply<L, T[K]>; }T,
lambda: L extends Lambdalambda: function (type parameter) L in <const T extends ReadonlyArray<unknown>, L extends Lambda>(self: T, lambda: L): { [K in keyof T]: Apply<L, T[K]>; }L
): { [function (type parameter) KK in keyof function (type parameter) T in <const T extends ReadonlyArray<unknown>, L extends Lambda>(self: T, lambda: L): { [K in keyof T]: Apply<L, T[K]>; }T]: type Apply<L extends Lambda, V> = (L & {
readonly "~lambda.in": V;
})["~lambda.out"]
Applies a
Lambda
type-level function to a value type V, producing
the output type.
When to use
Use when you need to compute what type a Lambda would produce for a
given input.
Details
This works by intersecting the Lambda with { "~lambda.in": V } and reading
"~lambda.out".
Example (Computing the output type of a lambda)
import type { Struct } from "effect"
interface ToString extends Struct.Lambda {
readonly "~lambda.out": string
}
// Result is `string`
type Result = Struct.Apply<ToString, number>
Apply<function (type parameter) L in <const T extends ReadonlyArray<unknown>, L extends Lambda>(self: T, lambda: L): { [K in keyof T]: Apply<L, T[K]>; }L, function (type parameter) T in <const T extends ReadonlyArray<unknown>, L extends Lambda>(self: T, lambda: L): { [K in keyof T]: Apply<L, T[K]>; }T[function (type parameter) KK]> }
} = dual<(...args: Array<any>) => any, <const T extends ReadonlyArray<unknown>, L extends Function>(self: T, lambda: L) => any[]>(arity: 2, body: <const T extends ReadonlyArray<unknown>, L extends Function>(self: T, lambda: L) => any[]): ((...args: Array<any>) => any) & (<const T extends ReadonlyArray<unknown>, L extends Function>(self: T, lambda: L) => any[]) (+1 overload)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 (Selecting data-first or data-last style by arity)
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 (Defining overloads with call signatures)
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 (Selecting data-first or data-last style with a predicate)
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
dual(
2,
<const function (type parameter) T in <const T extends ReadonlyArray<unknown>, L extends Function>(self: T, lambda: L): any[]T extends interface ReadonlyArray<T>ReadonlyArray<unknown>, function (type parameter) L in <const T extends ReadonlyArray<unknown>, L extends Function>(self: T, lambda: L): any[]L extends Function>(self: const T extends ReadonlyArray<unknown>self: function (type parameter) T in <const T extends ReadonlyArray<unknown>, L extends Function>(self: T, lambda: L): any[]T, lambda: L extends Functionlambda: function (type parameter) L in <const T extends ReadonlyArray<unknown>, L extends Function>(self: T, lambda: L): any[]L) => {
return self: const T extends ReadonlyArray<unknown>self.ReadonlyArray<unknown>.map<any>(callbackfn: (value: unknown, index: number, array: readonly unknown[]) => any, thisArg?: any): any[]Calls a defined callback function on each element of an array, and returns an array that contains the results.
map((e: unknowne) => lambda: L extends Functionlambda(e: unknowne))
}
)