如何在 fp-ts 中从 ReaderEither<R, E, A>[] 转到 ReaderEither<R, E[], A[]>?
How to go from ReaderEither<R, E, A>[] to ReaderEither<R, E[], A[]> in fp-ts?
在 fp-ts 中,如何从 ReaderEither<R, E, A>[]
转到 ReaderEither<R, E[], A[]>
?本质上,我想将 ReaderEither
个实例的数组转换为单个 ReaderEither
个实例。
我尝试寻找答案,但运气不佳。我是函数式编程和 fp-ts 的新手,所以我仍在努力理解所有概念并将它们付诸实践。感谢您的帮助。
试试这个:
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)
代码是这样做的:
sequence
s (from Traversable
)把ReaderEither<R, E, A>[]
改成Reader<R, Either<E, A>[]>
separate
s (from Compactable
) Either<E, A>[]
从 reader 变成 {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[]>
如果有任何Left
s,returns一个Left
具有Left
值,否则returns一个Right
与 Right
值。
在 fp-ts 中,如何从 ReaderEither<R, E, A>[]
转到 ReaderEither<R, E[], A[]>
?本质上,我想将 ReaderEither
个实例的数组转换为单个 ReaderEither
个实例。
我尝试寻找答案,但运气不佳。我是函数式编程和 fp-ts 的新手,所以我仍在努力理解所有概念并将它们付诸实践。感谢您的帮助。
试试这个:
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)
代码是这样做的:
sequence
s (fromTraversable
)把ReaderEither<R, E, A>[]
改成Reader<R, Either<E, A>[]>
separate
s (fromCompactable
)Either<E, A>[]
从 reader 变成{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[]>
如果有任何
Left
s,returns一个Left
具有Left
值,否则returns一个Right
与Right
值。