fp-tsでTaskEither->Either後の変換関連

TaskEitherの処理をするとEitherが取得できる。それの処理全般において順番に変数に値をつめてから処理をすることはできるが、関数合成をすることもできそう。そこらへんのメモ

## OKのみ

TE.ApplicativePar　を使うと１つにまとまる
T.ApplicativePar　を使うとそれぞれで処理する

```ts
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('配列１つ 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 })
  })
})
```

実行結果
```ts
{ 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　を使うとそれぞれで処理するため、影響なし

```ts
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('配列１つ 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 })
  })
})
```

実行結果
```ts
{ 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で結果取得して、実施先で分類されるパターン


```ts
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('配列１つ 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 })
  })
})
```

実行結果
```ts
{ do_result_array_isEven: { left: [ 1, 3, 5 ], right: [ 2, 4 ] } }
{
  separate_action_result_array_isEven: { left: [ 1, 3, 5 ], right: [ 2, 4 ] }
}
```