0

在 fp-ts 中,我如何从ReaderEither<R, E, A>[]ReaderEither<R, E[], A[]>?本质上,我想将实例数组转换为ReaderEither单个ReaderEither实例。

我试过寻找答案,但运气不佳。我是函数式编程和 fp-ts 的新手,所以我仍在尝试围绕所有概念并将它们付诸实践。我感谢您的帮助。

4

1 回答 1

1

试试这个:

import * as A from 'fp-ts/Array'
import {left, right} from 'fp-ts/Either'
import * as R from 'fp-ts/Reader'
import {flow} from 'fp-ts/function'
import type {ReaderEither} from 'fp-ts/ReaderEither'

const sequenceRE: <R, E, A>(
  fs: ReaderEither<R, E, A>[]
) => ReaderEither<R, E[], A[]> = flow(
  // ReaderEither<R, E, A>[] -> Reader<R, Either<E, A>[]>
  A.sequence(R.reader),
  // Maps the reader: Reader<R, Either<E, A>[]> -> ReaderEither<R, E[], A[]>
  R.map(flow(
    // Either<E, A>[] -> Separated<E[], A[]>
    A.separate,
    // Separated<E[], A[]> -> Either<E[], A[]>
    s => s.left.length ? left(s.left) : right(s.right)
  ))
)

// Right [4, 6]
sequenceRE([r => right(r * 2), r => right(r * 3)])(2)
// Left ['foo', 'bar']
sequenceRE([r => right(r * 2), r => left('foo'), r => left('bar')])(2)
// Right []
sequenceRE([])(2)

代码这样做:

  • sequences (from Traversable)ReaderEither<R, E, A>[]进入Reader<R, Either<E, A>[]>

  • separates (from Compactable)Either<E, A>[]从读者到{left: E[], right: A[]}

    interface Separated<A, B> {
      readonly left: A
      readonly right: B
    }
    
    // For Array:
    declare const separate: <A, B>(fa: Either<A, B>[]) => Separated<A[], B[]>
    
  • 如果有任何Lefts,则返回Left带有Left值的 a,否则返回Right带有Right值的 a。

于 2020-09-24T03:02:14.393 回答