簡體   English   中英

遍歷/序列和數組<either<e, a> &gt; 進入任何一個<array<e> , 數組<a>&gt; 在 fp-ts</a> </array<e></either<e,>

[英]Traverse/sequence and Array<Either<E, A>> into Either<Array<E>, Array<A>> in fp-ts

我有一個實體列表,即使一個失敗的驗證也會產生錯誤。 但是,我仍然想迭代整個列表並收集所有錯誤以供進一步記錄。

使用默認 Either's Applicative 的遍歷/序列將產生Either<E, A[]> (僅遇到第一個錯誤),而不是需要Either<E[], A[]>

庫中是否有默認工具來實現這一點,還是可以通過編寫自定義 Applicative 來實現?

沒有直接執行此操作的 fp-ts function,但您可以使用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實例。 applicative 實例將使用 semigroup 實例組合錯誤。

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)
)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM