You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

技术问询:如何将Either<A,B>[]转换为Either<A[],B[]>并实现错误收集规则

简化Either数组的类型转换实现

我们需要实现一个函数,将Either<A,B>[]类型转换为Either<A[],B[]>类型,转换规则如下:

  • 若数组中存在任意一个左值(错误),返回包含所有错误的左值
  • 若数组中无错误,返回包含所有正确结果的右值

以下是最初的实现代码,嵌套层级较多,逻辑不够直观:

const compress = <A, B>(arr: E.Either<A, B>[]): E.Either<A[], B[]> => 
  A.reduce(
    E.right([]),
    (acc: E.Either<A[], B[]>, v: E.Either<A, B>) => 
    E.match(
      (a: A) => E.match((aar: A[]) => E.left([...aar, a]), 
                        (bar: B[]) => E.left([a]))(acc),
      (b: B) => E.match((aar: A[]) => E.left(aar), 
                        (bar: B[]) => E.right([...bar, b]))(acc)
    )(v)
   )(arr);

简洁实现方案

利用fp-ts内置的E.partition函数,可以直接将Either数组拆分为左值数组和右值数组,再根据左值数组是否为空返回对应结果,代码逻辑清晰且简洁:

import * as E from 'fp-ts/Either'
import { pipe } from 'fp-ts/function'

const compress = <A, B>(arr: E.Either<A, B>[]): E.Either<A[], B[]> =>
  pipe(
    E.partition(arr), // 将Either数组拆分,得到{ left: A[], right: B[] }
    ({ left, right }) => left.length > 0 ? E.left(left) : E.right(right)
  )

方案说明

  • E.partition(arr):遍历输入的Either数组,自动把所有左值收集到left数组,右值收集到right数组
  • 检查left数组的长度,若不为空则返回包含所有错误的左值;否则返回包含所有正确结果的右值,完全符合需求

如果不想使用pipe,也可以写成更直白的形式:

import * as E from 'fp-ts/Either'

const compress = <A, B>(arr: E.Either<A, B>[]): E.Either<A[], B[]> => {
  const { left, right } = E.partition(arr)
  return left.length ? E.left(left) : E.right(right)
}

内容的提问来源于stack exchange,提问作者Michael Lorton

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 16:54:16