<A, B>(f: (a: NoInfer<A>, i: number) => B): (
self: Iterable<A>
) => Iterable<B>
<A, B>(self: Iterable<A>, f: (a: NoInfer<A>, i: number) => B): Iterable<B>Transforms each element of an iterable using a function.
Details
This is one of the most fundamental operations for working with iterables. It applies a transformation function to each element, creating a new iterable with the transformed values. The operation is lazy, so elements are only transformed when the iterable is consumed.
Example (Mapping elements)
import { Iterable } from "effect"
// Transform numbers to their squares
const numbers = [1, 2, 3, 4, 5]
const squares = Iterable.map(numbers, (x) => x * x)
console.log(Array.from(squares)) // [1, 4, 9, 16, 25]
// Use index in transformation
const indexed = Iterable.map(["a", "b", "c"], (char, i) => `${i}: ${char}`)
console.log(Array.from(indexed)) // ["0: a", "1: b", "2: c"]
// Chain transformations
const result = Iterable.map(
Iterable.map([1, 2, 3], (x) => x * 2),
(x) => x + 1
)
console.log(Array.from(result)) // [3, 5, 7]export const const map: {
<A, B>(f: (a: NoInfer<A>, i: number) => B): (
self: Iterable<A>
) => Iterable<B>
<A, B>(
self: Iterable<A>,
f: (a: NoInfer<A>, i: number) => B
): Iterable<B>
}
Transforms each element of an iterable using a function.
Details
This is one of the most fundamental operations for working with iterables.
It applies a transformation function to each element, creating a new iterable
with the transformed values. The operation is lazy, so elements are only
transformed when the iterable is consumed.
Example (Mapping elements)
import { Iterable } from "effect"
// Transform numbers to their squares
const numbers = [1, 2, 3, 4, 5]
const squares = Iterable.map(numbers, (x) => x * x)
console.log(Array.from(squares)) // [1, 4, 9, 16, 25]
// Use index in transformation
const indexed = Iterable.map(["a", "b", "c"], (char, i) => `${i}: ${char}`)
console.log(Array.from(indexed)) // ["0: a", "1: b", "2: c"]
// Chain transformations
const result = Iterable.map(
Iterable.map([1, 2, 3], (x) => x * 2),
(x) => x + 1
)
console.log(Array.from(result)) // [3, 5, 7]
map: {
<function (type parameter) A in <A, B>(f: (a: NoInfer<A>, i: number) => B): (self: Iterable<A>) => Iterable<B>A, function (type parameter) B in <A, B>(f: (a: NoInfer<A>, i: number) => B): (self: Iterable<A>) => Iterable<B>B>(
f: (a: NoInfer<A>, i: number) => Bf: (a: NoInfer<A>a: type NoInfer<A> = [A][A extends any ? 0 : never]Prevents TypeScript from inferring a type parameter from a specific
position.
When to use
Use when a function parameter must match an inferred type without becoming
an inference source.
Details
The parameter using NoInfer must still match the inferred type.
Example (Controlling inference)
import type { Types } from "effect"
declare function withDefault<T>(value: T, fallback: Types.NoInfer<T>): T
// T is inferred as "a" | "b" from the first argument only
const result = withDefault<"a" | "b">("a", "b")
NoInfer<function (type parameter) A in <A, B>(f: (a: NoInfer<A>, i: number) => B): (self: Iterable<A>) => Iterable<B>A>, i: numberi: number) => function (type parameter) B in <A, B>(f: (a: NoInfer<A>, i: number) => B): (self: Iterable<A>) => Iterable<B>B
): (self: Iterable<A>self: interface Iterable<T, TReturn = any, TNext = any>Iterable<function (type parameter) A in <A, B>(f: (a: NoInfer<A>, i: number) => B): (self: Iterable<A>) => Iterable<B>A>) => interface Iterable<T, TReturn = any, TNext = any>Iterable<function (type parameter) B in <A, B>(f: (a: NoInfer<A>, i: number) => B): (self: Iterable<A>) => Iterable<B>B>
<function (type parameter) A in <A, B>(self: Iterable<A>, f: (a: NoInfer<A>, i: number) => B): Iterable<B>A, function (type parameter) B in <A, B>(self: Iterable<A>, f: (a: NoInfer<A>, i: number) => B): Iterable<B>B>(self: Iterable<A>self: interface Iterable<T, TReturn = any, TNext = any>Iterable<function (type parameter) A in <A, B>(self: Iterable<A>, f: (a: NoInfer<A>, i: number) => B): Iterable<B>A>, f: (a: NoInfer<A>, i: number) => Bf: (a: NoInfer<A>a: type NoInfer<A> = [A][A extends any ? 0 : never]Prevents TypeScript from inferring a type parameter from a specific
position.
When to use
Use when a function parameter must match an inferred type without becoming
an inference source.
Details
The parameter using NoInfer must still match the inferred type.
Example (Controlling inference)
import type { Types } from "effect"
declare function withDefault<T>(value: T, fallback: Types.NoInfer<T>): T
// T is inferred as "a" | "b" from the first argument only
const result = withDefault<"a" | "b">("a", "b")
NoInfer<function (type parameter) A in <A, B>(self: Iterable<A>, f: (a: NoInfer<A>, i: number) => B): Iterable<B>A>, i: numberi: number) => function (type parameter) B in <A, B>(self: Iterable<A>, f: (a: NoInfer<A>, i: number) => B): Iterable<B>B): interface Iterable<T, TReturn = any, TNext = any>Iterable<function (type parameter) B in <A, B>(self: Iterable<A>, f: (a: NoInfer<A>, i: number) => B): Iterable<B>B>
} = dual<(...args: Array<any>) => any, <A, B>(self: Iterable<A>, f: (a: A, i: number) => B) => Iterable<B>>(arity: 2, body: <A, B>(self: Iterable<A>, f: (a: A, i: number) => B) => Iterable<B>): ((...args: Array<any>) => any) & (<A, B>(self: Iterable<A>, f: (a: A, i: number) => B) => Iterable<B>) (+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, <function (type parameter) A in <A, B>(self: Iterable<A>, f: (a: A, i: number) => B): Iterable<B>A, function (type parameter) B in <A, B>(self: Iterable<A>, f: (a: A, i: number) => B): Iterable<B>B>(self: Iterable<A>self: interface Iterable<T, TReturn = any, TNext = any>Iterable<function (type parameter) A in <A, B>(self: Iterable<A>, f: (a: A, i: number) => B): Iterable<B>A>, f: (a: A, i: number) => Bf: (a: Aa: function (type parameter) A in <A, B>(self: Iterable<A>, f: (a: A, i: number) => B): Iterable<B>A, i: numberi: number) => function (type parameter) B in <A, B>(self: Iterable<A>, f: (a: A, i: number) => B): Iterable<B>B): interface Iterable<T, TReturn = any, TNext = any>Iterable<function (type parameter) B in <A, B>(self: Iterable<A>, f: (a: A, i: number) => B): Iterable<B>B> => ({
[var Symbol: SymbolConstructorSymbol.SymbolConstructor.iterator: typeof Symbol.iteratorA method that returns the default iterator for an object. Called by the semantics of the
for-of statement.
iterator]() {
const const iterator: Iterator<A, any, any>iterator = self: Iterable<A>self[var Symbol: SymbolConstructorSymbol.SymbolConstructor.iterator: typeof Symbol.iteratorA method that returns the default iterator for an object. Called by the semantics of the
for-of statement.
iterator]()
let let i: numberi = 0
return {
Iterator<B, any, any>.next(...[value]: [] | [any]): IteratorResult<B, any>next() {
const const result: IteratorResult<A, any>result = const iterator: Iterator<A, any, any>iterator.Iterator<A, any, any>.next(...[value]: [] | [any]): IteratorResult<A, any>next()
if (const result: IteratorResult<A, any>result.done?: boolean | undefineddone) {
return { IteratorReturnResult<TReturn>.done: truedone: true, IteratorReturnResult<any>.value: anyvalue: var undefinedundefined }
}
return { IteratorYieldResult<TYield>.done?: false | undefineddone: false, IteratorYieldResult<B>.value: Bvalue: f: (a: A, i: number) => Bf(const result: IteratorYieldResult<A>result.IteratorYieldResult<A>.value: Avalue, let i: numberi++) }
}
}
}
}))