<B>(that: Iterable<B>): <A>(self: Iterable<A>) => Iterable<A | B>
<A, B>(self: Iterable<A>, that: Iterable<B>): Iterable<A | B>Concatenates two iterables, combining their elements.
When to use
Use to lazily concatenate two iterables while preserving order, yielding all
elements from self before that.
Details
The result is lazy. The iterator for that is not created or read until
self is exhausted.
Gotchas
If self is infinite or never completes, that is never reached.
Example (Concatenating iterables)
import { Iterable } from "effect"
const first = [1, 2, 3]
const second = [4, 5, 6]
const combined = Iterable.appendAll(first, second)
console.log(Array.from(combined)) // [1, 2, 3, 4, 5, 6]
// Works with different iterable types
const numbers = [1, 2]
const letters = "abc"
const mixed = Iterable.appendAll(numbers, letters)
console.log(Array.from(mixed)) // [1, 2, "a", "b", "c"]
// Lazy evaluation - only consumes what's needed
const infinite = Iterable.range(1)
const finite = [0, -1, -2]
const result = Iterable.take(Iterable.appendAll(finite, infinite), 5)
console.log(Array.from(result)) // [0, -1, -2, 1, 2]export const const appendAll: {
<B>(that: Iterable<B>): <A>(
self: Iterable<A>
) => Iterable<A | B>
<A, B>(
self: Iterable<A>,
that: Iterable<B>
): Iterable<A | B>
}
Concatenates two iterables, combining their elements.
When to use
Use to lazily concatenate two iterables while preserving order, yielding all
elements from self before that.
Details
The result is lazy. The iterator for that is not created or read until
self is exhausted.
Gotchas
If self is infinite or never completes, that is never reached.
Example (Concatenating iterables)
import { Iterable } from "effect"
const first = [1, 2, 3]
const second = [4, 5, 6]
const combined = Iterable.appendAll(first, second)
console.log(Array.from(combined)) // [1, 2, 3, 4, 5, 6]
// Works with different iterable types
const numbers = [1, 2]
const letters = "abc"
const mixed = Iterable.appendAll(numbers, letters)
console.log(Array.from(mixed)) // [1, 2, "a", "b", "c"]
// Lazy evaluation - only consumes what's needed
const infinite = Iterable.range(1)
const finite = [0, -1, -2]
const result = Iterable.take(Iterable.appendAll(finite, infinite), 5)
console.log(Array.from(result)) // [0, -1, -2, 1, 2]
appendAll: {
<function (type parameter) B in <B>(that: Iterable<B>): <A>(self: Iterable<A>) => Iterable<A | B>B>(that: Iterable<B>that: interface Iterable<T, TReturn = any, TNext = any>Iterable<function (type parameter) B in <B>(that: Iterable<B>): <A>(self: Iterable<A>) => Iterable<A | B>B>): <function (type parameter) A in <A>(self: Iterable<A>): Iterable<A | B>A>(self: Iterable<A>self: interface Iterable<T, TReturn = any, TNext = any>Iterable<function (type parameter) A in <A>(self: Iterable<A>): Iterable<A | B>A>) => interface Iterable<T, TReturn = any, TNext = any>Iterable<function (type parameter) A in <A>(self: Iterable<A>): Iterable<A | B>A | function (type parameter) B in <B>(that: Iterable<B>): <A>(self: Iterable<A>) => Iterable<A | B>B>
<function (type parameter) A in <A, B>(self: Iterable<A>, that: Iterable<B>): Iterable<A | B>A, function (type parameter) B in <A, B>(self: Iterable<A>, that: Iterable<B>): Iterable<A | B>B>(self: Iterable<A>self: interface Iterable<T, TReturn = any, TNext = any>Iterable<function (type parameter) A in <A, B>(self: Iterable<A>, that: Iterable<B>): Iterable<A | B>A>, that: Iterable<B>that: interface Iterable<T, TReturn = any, TNext = any>Iterable<function (type parameter) B in <A, B>(self: Iterable<A>, that: Iterable<B>): Iterable<A | B>B>): interface Iterable<T, TReturn = any, TNext = any>Iterable<function (type parameter) A in <A, B>(self: Iterable<A>, that: Iterable<B>): Iterable<A | B>A | function (type parameter) B in <A, B>(self: Iterable<A>, that: Iterable<B>): Iterable<A | B>B>
} = dual<(...args: Array<any>) => any, <A, B>(self: Iterable<A>, that: Iterable<B>) => Iterable<A | B>>(arity: 2, body: <A, B>(self: Iterable<A>, that: Iterable<B>) => Iterable<A | B>): ((...args: Array<any>) => any) & (<A, B>(self: Iterable<A>, that: Iterable<B>) => Iterable<A | 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>, that: Iterable<B>): Iterable<A | B>A, function (type parameter) B in <A, B>(self: Iterable<A>, that: Iterable<B>): Iterable<A | B>B>(self: Iterable<A>self: interface Iterable<T, TReturn = any, TNext = any>Iterable<function (type parameter) A in <A, B>(self: Iterable<A>, that: Iterable<B>): Iterable<A | B>A>, that: Iterable<B>that: interface Iterable<T, TReturn = any, TNext = any>Iterable<function (type parameter) B in <A, B>(self: Iterable<A>, that: Iterable<B>): Iterable<A | B>B>): interface Iterable<T, TReturn = any, TNext = any>Iterable<function (type parameter) A in <A, B>(self: Iterable<A>, that: Iterable<B>): Iterable<A | B>A | function (type parameter) B in <A, B>(self: Iterable<A>, that: Iterable<B>): Iterable<A | 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 iterA: Iterator<A, any, any>iterA = 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 doneA: booleandoneA = false
let let iterB: Iterator<B, any, any>iterB: interface Iterator<T, TReturn = any, TNext = any>Iterator<function (type parameter) B in <A, B>(self: Iterable<A>, that: Iterable<B>): Iterable<A | B>B>
return {
Iterator<A | B, any, any>.next(...[value]: [] | [any]): IteratorResult<A | B, any>next() {
if (!let doneA: booleandoneA) {
const const r: IteratorResult<A, any>r = const iterA: Iterator<A, any, any>iterA.Iterator<A, any, any>.next(...[value]: [] | [any]): IteratorResult<A, any>next()
if (const r: IteratorResult<A, any>r.done?: boolean | undefineddone) {
let doneA: booleandoneA = true
let iterB: Iterator<B, any, any>iterB = that: Iterable<B>that[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]()
return let iterB: Iterator<B, any, any>iterB.Iterator<B, any, any>.next(...[value]: [] | [any]): IteratorResult<B, any>next()
}
return const r: IteratorYieldResult<A>r
}
return let iterB: Iterator<B, any, any>iterB.Iterator<B, any, any>.next(...[value]: [] | [any]): IteratorResult<B, any>next()
}
}
}
})
)