在 <E>fp-ts 中将数组<Both<E, A>> 遍历/序列成 Both<Array<A>, Array>



我有一个实体列表,即使一次验证失败也会产生错误。然而,我仍然想迭代整个列表,并收集所有错误以进行进一步的日志记录。

具有默认"任一应用程序"的遍历/序列将产生Either<E, A[]>(仅第一次遇到错误(,而不是所需的Either<E[], A[]>

库中是否有默认的工具来实现这一点,或者可以通过编写自定义应用程序来实现?

没有fp-ts函数可以直接执行此操作,但您可以使用Either模块中的getApplicativeValidation

import * as E from 'fp-ts/lib/Either'
import * as RA from 'fp-ts/lib/ReadonlyArray'
import {pipe} from 'fp-ts/lib/function'
const collectErrors = <E, A>(
xs: readonly E.Either<E, A>[]
): E.Either<readonly E[], readonly A[]> =>
pipe(
xs,
RA.traverse(E.getApplicativeValidation(RA.getSemigroup<E>()))(
E.mapLeft(RA.of)
)
)
// Left(['a', 'b'])
collectErrors([E.left('a'), E.right(1), E.left('b'))])
// Right([1, 2])
collectErrors([E.right(1), E.right(2)])
// Right([])
collectErrors([])

其工作原理是getApplicativeValidation获取一个Semigroup实例并返回一个可与traverse一起使用的Applicative实例。应用实例将使用半群实例组合错误。

RA.traverse(
// The applicative instance for the either that will collect the errors 
// into an array
E.getApplicativeValidation(
// The semigroup instance for readonly E[], which concatenates the arrays
RA.getSemigroup<E>()
)
)(
// Turn each Either<E, A> into Either<readonly E[], A> by putting each error
// inside an array so they can be concatenated
E.mapLeft(RA.of)
)

相关内容

  • 没有找到相关文章

最新更新