<
DataLast extends (...args: Array<any>) => any,
DataFirst extends (...args: Array<any>) => any
>(
arity: Parameters<DataFirst>["length"],
body: DataFirst
): DataLast & DataFirst
<
DataLast extends (...args: Array<any>) => any,
DataFirst extends (...args: Array<any>) => any
>(
isDataFirst: (args: IArguments) => boolean,
body: DataFirst
): DataLast & DataFirstCreates 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))) // 5Example (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))) // 5Example (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))) // 5export const const dual: {
<
DataLast extends (...args: Array<any>) => any,
DataFirst extends (...args: Array<any>) => any
>(
arity: Parameters<DataFirst>["length"],
body: DataFirst
): DataLast & DataFirst
<
DataLast extends (...args: Array<any>) => any,
DataFirst extends (...args: Array<any>) => any
>(
isDataFirst: (args: IArguments) => boolean,
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 (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: {
<function (type parameter) DataLast in <DataLast extends (...args: Array<any>) => any, DataFirst extends (...args: Array<any>) => any>(arity: Parameters<DataFirst>["length"], body: DataFirst): DataLast & DataFirstDataLast extends (...args: any[]args: interface Array<T>Array<any>) => any, function (type parameter) DataFirst in <DataLast extends (...args: Array<any>) => any, DataFirst extends (...args: Array<any>) => any>(arity: Parameters<DataFirst>["length"], body: DataFirst): DataLast & DataFirstDataFirst extends (...args: any[]args: interface Array<T>Array<any>) => any>(
arity: Parameters<DataFirst>["length"]arity: type Parameters<
T extends (...args: any) => any
> = T extends (...args: infer P) => any
? P
: never
Obtain the parameters of a function type in a tuple
Parameters<function (type parameter) DataFirst in <DataLast extends (...args: Array<any>) => any, DataFirst extends (...args: Array<any>) => any>(arity: Parameters<DataFirst>["length"], body: DataFirst): DataLast & DataFirstDataFirst>["length"],
body: DataFirst extends (...args: Array<any>) => anybody: function (type parameter) DataFirst in <DataLast extends (...args: Array<any>) => any, DataFirst extends (...args: Array<any>) => any>(arity: Parameters<DataFirst>["length"], body: DataFirst): DataLast & DataFirstDataFirst
): function (type parameter) DataLast in <DataLast extends (...args: Array<any>) => any, DataFirst extends (...args: Array<any>) => any>(arity: Parameters<DataFirst>["length"], body: DataFirst): DataLast & DataFirstDataLast & function (type parameter) DataFirst in <DataLast extends (...args: Array<any>) => any, DataFirst extends (...args: Array<any>) => any>(arity: Parameters<DataFirst>["length"], body: DataFirst): DataLast & DataFirstDataFirst
<function (type parameter) DataLast in <DataLast extends (...args: Array<any>) => any, DataFirst extends (...args: Array<any>) => any>(isDataFirst: (args: IArguments) => boolean, body: DataFirst): DataLast & DataFirstDataLast extends (...args: any[]args: interface Array<T>Array<any>) => any, function (type parameter) DataFirst in <DataLast extends (...args: Array<any>) => any, DataFirst extends (...args: Array<any>) => any>(isDataFirst: (args: IArguments) => boolean, body: DataFirst): DataLast & DataFirstDataFirst extends (...args: any[]args: interface Array<T>Array<any>) => any>(
isDataFirst: (args: IArguments) => booleanisDataFirst: (args: IArgumentsargs: IArguments) => boolean,
body: DataFirst extends (...args: Array<any>) => anybody: function (type parameter) DataFirst in <DataLast extends (...args: Array<any>) => any, DataFirst extends (...args: Array<any>) => any>(isDataFirst: (args: IArguments) => boolean, body: DataFirst): DataLast & DataFirstDataFirst
): function (type parameter) DataLast in <DataLast extends (...args: Array<any>) => any, DataFirst extends (...args: Array<any>) => any>(isDataFirst: (args: IArguments) => boolean, body: DataFirst): DataLast & DataFirstDataLast & function (type parameter) DataFirst in <DataLast extends (...args: Array<any>) => any, DataFirst extends (...args: Array<any>) => any>(isDataFirst: (args: IArguments) => boolean, body: DataFirst): DataLast & DataFirstDataFirst
} = function(arity: | Parameters<DataFirst>["length"]
| ((args: IArguments) => boolean)
arity, body: DataFirst extends (...args: Array<any>) => anybody) {
if (typeof arity: | Parameters<DataFirst>["length"]
| ((args: IArguments) => boolean)
arity === "function") {
return function(this: anythis: any) {
return arity: (args: IArguments) => booleanarity(function (local var) arguments: IArgumentsarguments)
? body: DataFirst extends (...args: Array<any>) => anybody.CallableFunction.apply<any, any[], any>(this: (this: any, ...args: any[]) => any, thisArg: any, args: any[]): any (+1 overload)Calls the function with the specified object as the this value and the elements of specified array as the arguments.
apply(this, function (local var) arguments: IArgumentsarguments as any)
: ((self: anyself: any) => body: DataFirst
;(...args: Array<any>) => any
body(self: anyself, ...function (local var) arguments: IArgumentsarguments)) as any
}
}
switch (arity: Parameters<DataFirst>["length"]arity) {
case 0:
case 1:
throw new var RangeError: RangeErrorConstructor
new (message?: string, options?: ErrorOptions) => RangeError (+3 overloads)
RangeError(`Invalid arity ${arity: Parameters<DataFirst>["length"]arity}`)
case 2:
return function(a: anya, b: anyb) {
if (function (local var) arguments: IArgumentsarguments.IArguments.length: numberlength >= 2) {
return body: DataFirst
;(...args: Array<any>) => any
body(a: anya, b: anyb)
}
return function(self: anyself: any) {
return body: DataFirst
;(...args: Array<any>) => any
body(self: anyself, a: anya)
}
}
case 3:
return function(a: anya, b: anyb, c: anyc) {
if (function (local var) arguments: IArgumentsarguments.IArguments.length: numberlength >= 3) {
return body: DataFirst
;(...args: Array<any>) => any
body(a: anya, b: anyb, c: anyc)
}
return function(self: anyself: any) {
return body: DataFirst
;(...args: Array<any>) => any
body(self: anyself, a: anya, b: anyb)
}
}
default:
return function() {
if (function (local var) arguments: IArgumentsarguments.IArguments.length: numberlength >= arity: Parameters<DataFirst>["length"]arity) {
// @ts-expect-error
return body: DataFirst extends (...args: Array<any>) => anybody.CallableFunction.apply<any, any[], any>(this: (this: any, ...args: any[]) => any, thisArg: any, args: any[]): any (+1 overload)Calls the function with the specified object as the this value and the elements of specified array as the arguments.
apply(this, function (local var) arguments: IArgumentsarguments)
}
const const args: IArgumentsargs = function (local var) arguments: IArgumentsarguments
return function(self: anyself: any) {
return body: DataFirst
;(...args: Array<any>) => any
body(self: anyself, ...const args: IArgumentsargs)
}
}
}
}