TaskEitherの処理をするとEitherが取得できる。それの処理全般において順番に変数に値をつめてから処理をすることはできるが、関数合成をすることもできそう。そこらへんのメモ
OKのみ
TE.ApplicativePar を使うと1つにまとまる
T.ApplicativePar を使うとそれぞれで処理する
import { describe, it } from 'vitest'
import * as TE from 'fp-ts/TaskEither'
import { pipe } from 'fp-ts/lib/function'
import * as T from 'fp-ts/Task'
import * as RA from 'fp-ts/ReadonlyArray'
describe('配列の結果取得の方法', () => {
it('配列1つ OKのみ', async () => {
const sample = [1, 2, 3, 4, 5]
const mapper_one = RA.traverse(TE.ApplicativePar)(TE.right)
const action_one = pipe(sample, mapper_one)
const result_one = await action_one()
console.log({ result_one })
const mapper_array = RA.traverse(T.ApplicativePar)(TE.right)
const action_array = pipe(sample, mapper_array)
const result_array = await action_array()
console.log({ result_array })
})
})
実行結果
{ result_one: { _tag: 'Right', right: [ 1, 2, 3, 4, 5 ] } }
{
result_array: [
{ _tag: 'Right', right: 1 },
{ _tag: 'Right', right: 2 },
{ _tag: 'Right', right: 3 },
{ _tag: 'Right', right: 4 },
{ _tag: 'Right', right: 5 }
]
}
OKとNGがある
TE.ApplicativePar はNGがあると、そこで終了する
T.ApplicativePar を使うとそれぞれで処理するため、影響なし
import { describe, it } from 'vitest'
import * as TE from 'fp-ts/TaskEither'
import { pipe } from 'fp-ts/lib/function'
import * as T from 'fp-ts/Task'
import * as RA from 'fp-ts/ReadonlyArray'
describe('配列の結果取得の方法', () => {
it('配列1つ OK/NG', async () => {
const sample = [1, 2, 3, 4, 5]
const isEven = (num: number) => {
return num % 2 === 0 ? TE.right<number, number>(num) : TE.left(num)
}
const mapper_one_isEven = RA.traverse(TE.ApplicativePar)(isEven)
const action_one_isEven = pipe(sample, mapper_one_isEven)
const result_one_isEven = await action_one_isEven()
console.log({ result_one_isEven })
const mapper_array_isEven = RA.traverse(T.ApplicativePar)(isEven)
const action_array_isEven = pipe(sample, mapper_array_isEven)
const result_array_isEven = await action_array_isEven()
console.log({ result_array_isEven })
})
})
実行結果
{ result_one_isEven: { _tag: 'Left', left: 1 } }
{
result_array_isEven: [
{ _tag: 'Left', left: 1 },
{ _tag: 'Right', right: 2 },
{ _tag: 'Left', left: 3 },
{ _tag: 'Right', right: 4 },
{ _tag: 'Left', left: 5 }
]
}
OKとNGがあり、それを分類する
T.ApplicativePar で取得した結果を分類するための方法2種類
- T.Do を使用して結果を取得して、それに対する処理まで関数合成するパターン
- いったんawaitで結果取得して、実施先で分類されるパターン
import { describe, it } from 'vitest'
import * as TE from 'fp-ts/TaskEither'
import { pipe } from 'fp-ts/lib/function'
import * as T from 'fp-ts/Task'
import * as RA from 'fp-ts/ReadonlyArray'
describe('配列の結果取得の方法', () => {
it('配列1つ OK/NG 分類あり', async () => {
const sample = [1, 2, 3, 4, 5]
const isEven = (num: number) => {
return num % 2 === 0 ? TE.right<number, number>(num) : TE.left(num)
}
const mapper_array_isEven = RA.traverse(T.ApplicativePar)(isEven)
const action_array_isEven = pipe(sample, mapper_array_isEven)
// 一度に全部やる
const do_array_isEven = pipe(
T.Do,
T.bind('result', () => action_array_isEven),
T.map(({ result }) => pipe(result, RA.separate))
)
const do_result_array_isEven = await do_array_isEven()
console.log({ do_result_array_isEven })
// 実施した後に分類する
const action_result_array_isEven = await action_array_isEven()
const separate_action_result_array_isEven = pipe(action_result_array_isEven, RA.separate)
console.log({ separate_action_result_array_isEven })
})
})
実行結果
{ do_result_array_isEven: { left: [ 1, 3, 5 ], right: [ 2, 4 ] } }
{
separate_action_result_array_isEven: { left: [ 1, 3, 5 ], right: [ 2, 4 ] }
}