gpt4 book ai didi

typescript - 如何避免 fp-ts 中带有链的厄运金字塔?

转载 作者:行者123 更新时间:2023-12-05 01:09:57 25 4
gpt4 key购买 nike

我经常遇到这种情况,需要完成几个顺序操作。如果每个操作都只使用上一步的数据,那么我可以很高兴地做类似 pipe(startingData, TE.chain(op1), TE.chain(op2), TE.chain(op3), ...) 。当 op2 还需要来自 startingData 的数据,而没有一堆嵌套回调时,我找不到写这个的好方法。

如何避免下例中的末日金字塔?

declare const op1: (x: {one: string}) => TE.TaskEither<Error, string>;
declare const op2: (x: {one: string, two: string}) => TE.TaskEither<Error, string>;
declare const op3: (x: {one: string, two: string, three: string}) => TE.TaskEither<Error, string>;

pipe(
TE.of<Error, string>('one'),
TE.chain((one) =>
pipe(
op1({ one }),
TE.chain((two) =>
pipe(
op2({ one, two }),
TE.chain((three) => op3({ one, two, three }))
)
)
)
)
);

最佳答案

有一个解决问题的方法,它被称为“do notation”。它在 fp-ts-contrib 中已经有一段时间了,但现在它也有一个使用 bind 嵌入到 fp-ts 本身的版本函数(在所有单子(monad)类型上定义)。基本思想类似于我在下面所做的 - 我们将计算结果绑定(bind)到特定名称,并在我们进行时在“上下文”对象中跟踪这些名称。代码如下:

pipe(
TE.of<Error, string>('one'),
TE.bindTo('one'), // start with a simple struct {one: 'one'}
TE.bind('two', op1), // the payload now contains `one`
TE.bind('three', op2), // the payload now contains `one` and `two`
TE.bind('four', op3), // the payload now contains `one` and `two` and `three`
TE.map(x => x.four) // we can discharge the payload at any time
)

原始答案如下

我提出了一个我不太引以为豪的解决方案,但我正在分享它以获得可能的反馈!

首先,定义一些辅助函数:

function mapS<I, O>(f: (i: I) => O) {
return <R extends { [k: string]: I }>(vals: R) =>
Object.fromEntries(Object.entries(vals).map(([k, v]) => [k, f(v)])) as {
[k in keyof R]: O;
};
}
const TEofStruct = <R extends { [k: string]: any }>(x: R) =>
mapS(TE.of)(x) as { [K in keyof R]: TE.TaskEither<unknown, R[K]> };

mapS 允许我将函数应用于对象中的所有值(子问题 1:是否有内置函数可以让我这样做?)。 TEofStruct 使用此函数将值的结构转换为这些值的 TaskEither 结构。

我的基本想法是使用 TEofStructsequenceS 将新值与以前的值一起累积。到目前为止,它看起来像这样:

pipe(
TE.of({
one: 'one',
}),
TE.chain((x) =>
sequenceTE({
two: op1(x),
...TEofStruct(x),
})
),
TE.chain((x) =>
sequenceTE({
three: op2(x),
...TEofStruct(x),
})
),
TE.chain((x) =>
sequenceTE({
four: op3(x),
...TEofStruct(x),
})
)
);

感觉我可以编写一些将 sequenceTETEofStruct 结合起来的辅助函数来减少这里的样板,但我仍然不确定这是否是正确的方法,或者是否有更惯用的模式!

关于typescript - 如何避免 fp-ts 中带有链的厄运金字塔?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64719416/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com