0Pricing
JavaScript Academy · レッスン

pipe と compose を作成する

左から右、または右から左への関数合成を実装します。

「pipe と compose を作成する」はCoddyKit上の無料JavaScript Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはJavaScript Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 JavaScript Academyコースには全4レッスンが含まれています。

2つの関数から多数の関数へ

2つの引数を取るcomposeには制限があります。実際のパイプラインでは、多くの手順を連鎖させます。このレッスンでは、reduceとreduceRightを使って汎用的なcomposeとpipeを作成します。

pipe:左から右へ

pipeは実行順に読みます。最初の関数が最初に実行されます。pipe(a, b, c)(x)はc(b(a(x)))と等しくなります。多くの人にとって、composeより自然に感じられる書き方です。

const pipe = (...fns) => x => fns.reduce((acc, fn) => fn(acc), x);

const inc = n => n + 1;
const double = n => n * 2;

console.log(pipe(inc, double)(5));

reduceがpipeを動かす仕組み

reduceは入力値をアキュムレーターの初期値として始め、各関数を順番に適用します。それぞれの結果が次の関数に渡されます。初期値xが連鎖の起点になります。

const pipe = (...fns) => x => fns.reduce((acc, fn) => fn(acc), x);

const steps = pipe(
  n => n + 1,
  n => n * 3,
  n => n - 2
);

console.log(steps(4));

reduceRightを使った compose

composeはpipeを逆向きにしたものです。reduceRightを使うと関数のリストを末尾からたどるため、右端の関数が最初に実行され、f(g(x))と一致します。

const compose = (...fns) => x => fns.reduceRight((acc, fn) => fn(acc), x);

const inc = n => n + 1;
const double = n => n * 2;

console.log(compose(inc, double)(5));

pipeとcomposeは対になる

同じ関数のリストでも、pipeとcomposeでは方向が反転するため結果が異なります。手順をどのように読ませたいかに応じて選択してください。

const pipe = (...fns) => x => fns.reduce((acc, fn) => fn(acc), x);
const compose = (...fns) => x => fns.reduceRight((acc, fn) => fn(acc), x);

const inc = n => n + 1;
const square = n => n * n;

console.log(pipe(inc, square)(3));
console.log(compose(inc, square)(3));

逆向きのpipeとしてのcompose

関数のリストを逆順にすることで、pipeを使ってcomposeを定義できます。これにより、両者が非常に近い関係にあることがわかります。

const pipe = (...fns) => x => fns.reduce((acc, fn) => fn(acc), x);
const compose = (...fns) => pipe(...fns.reverse());

const inc = n => n + 1;
const double = n => n * 2;

console.log(compose(inc, double)(5));

実際のテキストパイプライン

pipeを使い、小さな文字列関数からスラッグ生成器を作成します。各手順が1つの役割を担うため、単独で簡単にテストできます。

const pipe = (...fns) => x => fns.reduce((acc, fn) => fn(acc), x);

const slugify = pipe(
  s => s.trim(),
  s => s.toLowerCase(),
  s => s.replace(/\s+/g, '-')
);

console.log(slugify('  Hello World Example  '));

配列操作の合成

パイプラインは配列を含む任意のデータ型で機能します。フィルタリングとマッピングを、名前付きの1つの変換に組み合わせます。

const pipe = (...fns) => x => fns.reduce((acc, fn) => fn(acc), x);

const process = pipe(
  arr => arr.filter(n => n % 2 === 0),
  arr => arr.map(n => n * 10)
);

console.log(process([1, 2, 3, 4, 5, 6]));

恒等関数としてのエッジケース

関数を指定せずにpipe()を呼び出すと、入力がそのまま返されます。reduceがシードをそのまま返すためです。この恒等的な動作により、手順が0個でもヘルパーを安全に呼び出せます。

const pipe = (...fns) => x => fns.reduce((acc, fn) => fn(acc), x);

const identity = pipe();
console.log(identity(42));
console.log(identity('unchanged'));

カリー化との組み合わせ

カリー化された関数や部分適用された関数は、パイプラインにそのまま組み込めます。それぞれが、明確な1引数の手順になります。

const pipe = (...fns) => x => fns.reduce((acc, fn) => fn(acc), x);
const add = a => b => a + b;
const times = a => b => a * b;

const calc = pipe(add(3), times(2), add(-1));
console.log(calc(5));

pipeとcomposeの選び方

実行順に上から下へ手順を読ませたい場合はpipeを使います。数学的なf(g(x))表記に合わせたい場合はcomposeを使います。どちらも1行のreduceラッパーであり、関数型ライブラリで広く使われています。

const pipe = (...fns) => x => fns.reduce((acc, fn) => fn(acc), x);

const normalize = pipe(
  s => s.trim(),
  s => s.replace(/[^a-z0-9]+/gi, ' '),
  s => s.toUpperCase()
);

console.log(normalize('  a-b_c!d  '));

理解度チェック

composeが関数を右から左へ実行するのに使われる配列メソッドはどれですか。

まとめ:pipeとcompose

汎用的な関数合成ヘルパーを作成しました。

  • pipeはreduceを使って左から右へ実行します。
  • composeはreduceRightを使って右から左へ実行します。
  • composeは、リストを逆順にしたpipeとして定義できます。
  • 空のパイプラインは恒等的に動作し、カリー化された手順もきれいに組み込めます。

よくある質問

「pipe と compose を作成する」レッスンは無料ですか?

はい。「pipe と compose を作成する」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、JavaScript Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 JavaScript Academyコースには全4レッスンが含まれています。

「pipe と compose を作成する」で何を学びますか?

左から右、または右から左への関数合成を実装します。 ブラウザで直接実行するハンズオンコードでJavaScript Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

JavaScript Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのJavaScript Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。

「pipe と compose を作成する」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このJavaScript Academyレッスンでコードを書いて実行できますか?

はい。すべてのJavaScript Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. 部分適用
  2. 関数のカリー化
  3. 関数合成
  4. pipe と compose を作成する
← JavaScript Academyに戻る