我有一个实体列表,在这些实体中,即使一个验证失败也会产生错误。但是,我仍然希望迭代整个列表并收集所有的错误,以便进行进一步的记录。
具有默认应用程序的遍历/序列将产生Either<E, A[]> (仅是第一个遇到的错误),而不是需要的Either<E[], A[]>。
库中是否存在实现这一目标的默认工具,或者是否可以通过编写自定义应用程序来实现?
发布于 2022-08-09 01:33:53
没有直接这样做的fp函数,但是您可以使用来自Either模块的Either:
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)
)https://stackoverflow.com/questions/73259163
复制相似问题