如何使用扩展运算符调用重载函数
how to call an overloaded function with the spread operator
我想使用扩展运算符从 fp-ts 调用 pipe function,但它没有为此重载。
相反,我不得不将 pipe
转换为 any,这看起来很难看并且会损害可读性。
我可以扩充现有类型吗?
我创建了这个简单的示例,这里是 codesandbox。现实世界的例子使我无法确切知道我将传递给管道的参数数量。
import { pipe } from "fp-ts/function";
const o = { a: "a", b: "b", c: "c" };
type O = typeof o;
type G = (o: O) => O;
const set = (...getters: G[]) => {
/*
Expected 1-20 arguments, but got 0 or more.ts(2556)
function.d.ts(225, 33): An argument for 'a' was not
*/
return pipe(...getters);
// this works but is ugly
// return (pipe as any)(...getters);
};
const getters: G[] = [
(o: O) => ({ ...o, a: "5" }),
(o: O) => ({ ...o, b: "6" }),
(o: O) => ({ ...o, c: "8" })
];
set(...getters);
你能试试下面的方法吗?
const getters = [
(o: O) => ({ ...o, a: "5" }),
(o: O) => ({ ...o, b: "6" }),
(o: O) => ({ ...o, c: "8" })
] as const;
const lotsOfO = pipe(o, ...getters);
getters
必须是常量,以便 typescript 推断出正确的重载形式,即在这种情况下的参数数量。
我认为这是幺半群的工作。
import { foldMap } from "fp-ts/Array";
import { getEndomorphismMonoid } from "fp-ts/lib/Monoid";
import { identity, pipe } from "fp-ts/lib/function";
const o = { a: "a", b: "b", c: "c" };
type O = typeof o;
type G = (o: O) => O;
const monoid = getEndomorphismMonoid<O>();
const set = (getters: G[]) => pipe(getters, foldMap(monoid)(identity));
const getters: G[] = [
(o: O) => ({ ...o, a: "5" }),
(o: O) => ({ ...o, b: "6" }),
(o: O) => ({ ...o, c: "8" }),
];
console.log(set(getters)(o));
不知道大家是否熟悉Monoid,一个monoid就是typeclass有两个函数。
concat
和 empty
concat 是获取两个值并将其连接在一起的函数,而 empty 是当您的类型没有任何值时它将获得空值。
例如 monoid for sum 是这样的
const monoidSum: Monoid<number> = {
concat: (x, y) => x + y,
empty: 0
}
您可以在数组的 foldMap
上使用此 monoidSum
并获得整数列表的总和。
这里我们使用了一个名为getEndomorphismMonoid
的函数,这是一个内置于fp-ts
中的函数。 Endmorphism 表示一个函数接受一个参数作为输入并且 return 相同类型。
export interface Endomorphism<A> {
(a: A): A
}
对于 concat,它将两个函数连接在一起,对于空的,它使用 identity
函数。
我想使用扩展运算符从 fp-ts 调用 pipe function,但它没有为此重载。
相反,我不得不将 pipe
转换为 any,这看起来很难看并且会损害可读性。
我可以扩充现有类型吗?
我创建了这个简单的示例,这里是 codesandbox。现实世界的例子使我无法确切知道我将传递给管道的参数数量。
import { pipe } from "fp-ts/function";
const o = { a: "a", b: "b", c: "c" };
type O = typeof o;
type G = (o: O) => O;
const set = (...getters: G[]) => {
/*
Expected 1-20 arguments, but got 0 or more.ts(2556)
function.d.ts(225, 33): An argument for 'a' was not
*/
return pipe(...getters);
// this works but is ugly
// return (pipe as any)(...getters);
};
const getters: G[] = [
(o: O) => ({ ...o, a: "5" }),
(o: O) => ({ ...o, b: "6" }),
(o: O) => ({ ...o, c: "8" })
];
set(...getters);
你能试试下面的方法吗?
const getters = [
(o: O) => ({ ...o, a: "5" }),
(o: O) => ({ ...o, b: "6" }),
(o: O) => ({ ...o, c: "8" })
] as const;
const lotsOfO = pipe(o, ...getters);
getters
必须是常量,以便 typescript 推断出正确的重载形式,即在这种情况下的参数数量。
我认为这是幺半群的工作。
import { foldMap } from "fp-ts/Array";
import { getEndomorphismMonoid } from "fp-ts/lib/Monoid";
import { identity, pipe } from "fp-ts/lib/function";
const o = { a: "a", b: "b", c: "c" };
type O = typeof o;
type G = (o: O) => O;
const monoid = getEndomorphismMonoid<O>();
const set = (getters: G[]) => pipe(getters, foldMap(monoid)(identity));
const getters: G[] = [
(o: O) => ({ ...o, a: "5" }),
(o: O) => ({ ...o, b: "6" }),
(o: O) => ({ ...o, c: "8" }),
];
console.log(set(getters)(o));
不知道大家是否熟悉Monoid,一个monoid就是typeclass有两个函数。
concat
和 empty
concat 是获取两个值并将其连接在一起的函数,而 empty 是当您的类型没有任何值时它将获得空值。
例如 monoid for sum 是这样的
const monoidSum: Monoid<number> = {
concat: (x, y) => x + y,
empty: 0
}
您可以在数组的 foldMap
上使用此 monoidSum
并获得整数列表的总和。
这里我们使用了一个名为getEndomorphismMonoid
的函数,这是一个内置于fp-ts
中的函数。 Endmorphism 表示一个函数接受一个参数作为输入并且 return 相同类型。
export interface Endomorphism<A> {
(a: A): A
}
对于 concat,它将两个函数连接在一起,对于空的,它使用 identity
函数。