見出し画像

fp-tsライブラリを使ったchunksOf,chain,traverseのワークアラウンドの紹介

こんにちわ。nap5です。

fp-tsライブラリを使ったchunksOf,chain,traverseのワークアラウンドの紹介したいと思います。



まずは、配列のタスクを並列処理でシークエンスさせて実行します。

import * as T from "fp-ts/Task";
import { sequenceT } from "fp-ts/lib/Apply";
import { pipe } from "fp-ts/lib/function";
import { chunksOf, map } from "fp-ts/lib/Array";

(async () => {
  const f = (nuts: number[]): number[] => {
    return nuts;
  };
  const nuts = sequenceT(T.ApplicativePar)(
    T.of(1),
    T.of(2),
    T.of(3),
    T.of(4),
    T.of(5)
  );
  console.log(await nuts());
  pipe(
    await nuts(),
    chunksOf(2),
    map((x) => x as unknown as number[]),
    map((ids) => f(ids)),
    console.log
  );
})();


実行結果になります。チャンクが2でパーティションしたので、以下のようにグルーピングされています。

$ yarn do src/1.ts
[ 1, 2, 3, 4, 5 ]
[ [ 1, 2 ], [ 3, 4 ], [ 5 ] ]


次に、chainで配列データを引数に受け取り、処理関数に流し込みます。

import * as T from "fp-ts/Task";
import { sequenceT } from "fp-ts/lib/Apply";
import { pipe } from "fp-ts/lib/function";
import { chain, chunksOf, map } from "fp-ts/lib/Array";

(async () => {
  const f = (nuts: number[]): number[] => {
    return nuts;
  };
  const nuts = sequenceT(T.ApplicativePar)(
    T.of(1),
    T.of(2),
    T.of(3),
    T.of(4),
    T.of(5)
  );
  console.log(await nuts());
  pipe(
    await nuts(),
    chunksOf(2),
    map((x) => x as unknown as number[]),
    chain((ids) => f(ids)),
    console.log
  );
})();


実行結果になります。入力と出力が同じデータ構造になったので、chainはreduceのように前回結果に対してconcatして単一の配列データを生成してくれることが分かります。

$ yarn do src/2.ts
[ 1, 2, 3, 4, 5 ]
[ 1, 2, 3, 4, 5 ]



最後にtraverseを使った場合です。

import * as T from "fp-ts/Task";
import { sequenceT } from "fp-ts/lib/Apply";
import { pipe } from "fp-ts/lib/function";
import { Applicative, chain, chunksOf, map, traverse } from "fp-ts/lib/Array";

(async () => {
  const f = (n: number): number[] => {
    console.log(n);
    return [n];
  };
  const nuts = sequenceT(T.ApplicativePar)(
    T.of(1),
    T.of(2),
    T.of(3),
    T.of(4),
    T.of(5)
  );
  console.log(await nuts());
  pipe(
    await nuts(),
    chunksOf(2),
    map((x) => x as unknown as number[]),
    chain((ids) => {
      console.log(ids);
      return traverse(Applicative)(f)(ids);
    }),
    console.log
  );
})();


実行結果になります。グルーピングされた配列データをtraverseで単一アイテムごとに関数へ引き渡すことができます。このとき、applicativeを指定して処理方式なども指定したりできます。今回はそのままバニラで何もしないものです。出力結果はグルーピングされた状態で出力されています。

$ yarn do src/3.ts
[ 1, 2, 3, 4, 5 ]
[ 1, 2 ]
1
2
[ 3, 4 ]
3
4
[ 5 ]
5
[ [ 1, 2 ], [ 3, 4 ], [ 5 ] ]


デモコードです。



簡単ですが、以上です。

この記事が気に入ったらサポートをしてみませんか?