fp-ts如何映射包装值 合并嵌套pipe实现TaskEither数组转换
回答
完全可以把嵌套的pipe改写成单pipe实现,你需要的数组类型转换也有更简洁的标准写法,不需要手动嵌套。
首先明确核心逻辑:你当前内层pipe做的事,本质是遍历funds数组,对每个元素执行返回TaskEither的异步请求,再把所有请求的结果合并成单个TaskEither包裹的数组。fp-ts的TaskEither模块已经内置了TE.traverseArray算子专门处理这个场景,不需要手动写map + TE.sequenceArray的组合。
改写后的单pipe版本代码如下:
const result: TE.TaskEither<DataTransferError, readonly CoinMetadataDto[]> = pipe( this.ensureFundsExist(), TE.chain(TE.traverseArray( fund => this.coinGeckoAdapter.getCoinMetadata(fund.coinGeckoId) )) );
这里TE.traverseArray接收一个「单个元素转TaskEither」的函数,会直接返回一个「数组转TaskEither包裹的结果数组」的函数,刚好匹配TE.chain的入参要求,全程只需要一层pipe。
关于你问的「能不能直接通过map完成TaskEither<E, Data[]>到TaskEither<E, OtherData[]>的转换」,要分两种情况判断:
- 如果
Data到OtherData的转换是纯同步计算,不会产生错误、不需要异步执行,那直接用TE.map搭配数组原生map即可:pipe( fetchDataTaskEither, TE.map(dataList => dataList.map(/* 同步纯转换逻辑 */)) ) - 如果转换逻辑本身会返回
TaskEither(比如你代码里的接口请求,可能失败、属于异步操作),就不能直接用TE.map——TE.map只能处理包裹在TaskEither里的纯值转换,不会合并新产生的TaskEither错误/异步上下文,这种场景必须用TE.chain配合遍历算子。
如果你出于某些原因不想用TE.traverseArray,坚持保留手动map + TE.sequenceArray的逻辑,你现在写的嵌套pipe本身是合法可运行的,只是多了一层不必要的嵌套而已,逻辑上没有问题。
内容的提问来源于stack exchange,提问作者Adam A
相关产品推荐
相关产品推荐

