【发布时间】:2022-01-04 17:16:45
【问题描述】:
给定一个结构,其中每个属性的类型为 These<E, A>,其中 E 和 A 对于每个属性都不同。
declare const someStruct: {
a1: TH.These<E1, A1>;
a2: TH.These<E2, A2>;
a3: TH.These<E3, A3>;
}
我正在这样对待These
- 左:严重错误,计算失败
- 正确:计算成功
- 两者:轻微错误/警告,继续计算
现在我正在寻找一种方法来组合上述结构的结果
declare function merge(struct: Record<string, TH.These<unknown, unknown>>): E.Either<CriticalErrorLeftOnly, {
warnings: unknown[]; // these would be the E of Both
value: Record<string, unknown>;
}>
如果我可以做到sequenceS(E.Apply)(someStruct)。但这在这里行不通,因为它也会为两者返回一个左键。
编辑:
这些
第二次编辑: 这是我想要实现的 POC .. 基本上获得结构的所有权利和两个值,同时聚合左侧。然而它并不完全在那里,因为结果还包含类型为 never 的 lefty 属性
import * as ROA from 'fp-ts/ReadonlyArray';
import * as TH from 'fp-ts/These';
import * as E from 'fp-ts/Either';
type PropertyKey = string | number | symbol;
type AnyRightThese = TH.These<any, any>;
type PropertyError<Properties> = { key: keyof Properties; error: Core.Error.Type };
type UnwrapRight<T> = T extends E.Right<infer A> ? A : never;
export const collect = <Properties extends Record<PropertyKey, AnyRightThese>>(
properties: Properties,
): TH.These<
PropertyError<Properties>[],
{
[K in keyof Properties]: UnwrapRight<Properties[K]>;
}
> => {
const errorsAndWarnings: PropertyError<Properties>[] = [];
const rights: any = {};
let isBoth = true;
for (const k in properties) {
const de = properties[k];
if (TH.isLeft(de)) {
isBoth = false;
errorsAndWarnings.push({ key: k, error: de.left });
} else if (TH.isRight(de)) {
rights[k] = de.right;
} else {
errorsAndWarnings.push({ key: k, error: de.left });
rights[k] = de.right;
}
}
return ROA.isNonEmpty(errorsAndWarnings)
? isBoth
? TH.both(errorsAndWarnings, rights)
: TH.left(errorsAndWarnings)
: TH.right(rights);
};
// example
const struct = {
a: TH.right(1),
b: TH.left('foo'),
c: TH.both(10, 'foobar'),
};
const a = collect(struct);
if (TH.isRight(a)) {
a.right.b; // b should not be part of a as it is of type never
}
【问题讨论】:
-
什么是
These?请分享该类型的定义。 -
更新了问题。这些值可以是 E、A 或两者,来自 fp-ts:gcanti.github.io/fp-ts/modules/These.ts.html
-
问题是如何输入(使用泛型而不是
unknown)还是如何实现?对于后者,我怀疑你会做自己的matchW事情 -
These<A, B>等价于Either<A, Either<B, Tuple<A, B>。考虑到这一点,您可以构造有效的函子、应用程序和可遍历的实例。这是implementation in purescript
标签: typescript functional-programming fp-ts