関数合成
小さな関数を組み合わせてパイプラインを作成します。
「関数合成」はCoddyKit上の無料JavaScript Academyレッスンです。 これはレッスン3/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはJavaScript Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 JavaScript Academyコースには全4レッスンが含まれています。
関数合成とは
関数合成は、小さな関数を1つに組み合わせる方法です。fとgを合成すると、gの出力がfの入力になる関数が生成されます。
数学的には、compose(f, g)(x) = f(g(x))です。データは右から左へ流れます。
2つの小さな関数
合成は、単純で単一の目的を持つ関数から始まります。ここでは、組み合わせる2つの変換を見てみましょう。
const double = x => x * 2;
const increment = x => x + 1;
console.log(double(5));
console.log(increment(5));手作業で合成する
最も明示的な合成は、ある関数の結果を別の関数に渡して呼び出すだけです。内側から外側へ読みます。まずincrementが実行され、次にdoubleが実行されます。
const double = x => x * 2;
const increment = x => x + 1;
const result = double(increment(5));
console.log(result);2つの関数用の compose 関数
このパターンを再利用可能なcomposeでラップします。fとgを受け取り、まずgを適用してからfを適用する新しい関数を返します。
const compose = (f, g) => x => f(g(x));
const double = x => x * 2;
const increment = x => x + 1;
const doubleThenAfterIncrement = compose(double, increment);
console.log(doubleThenAfterIncrement(5));順序が重要
合成は可換ではありません。右側の関数が先に実行されるため、compose(f, g)とcompose(g, f)は異なります。
const compose = (f, g) => x => f(g(x));
const double = x => x * 2;
const increment = x => x + 1;
console.log(compose(double, increment)(5));
console.log(compose(increment, double)(5));右から左へ読む
compose(a, b, c)(x)という呼び出しは、a(b(c(x)))として評価されます。一番右の関数が最初に入力を処理します。バグを避けるため、この方向を意識してください。
const compose = (f, g) => x => f(g(x));
const shout = s => s.toUpperCase();
const exclaim = s => s + '!';
const loud = compose(shout, exclaim);
console.log(loud('hello'));文字列変換の合成
合成はテキスト処理のパイプラインに適しています。trim、lowercase、そして空白の置換という各処理を、小さな関数として組み合わせられます。
const compose = (f, g) => x => f(g(x));
const trim = s => s.trim();
const lower = s => s.toLowerCase();
const clean = compose(lower, trim);
console.log(clean(' HELLO World '));数値処理の合成
数学的な演算を連鎖させるのは、典型的な例です。各関数を単独で簡単にテストできる状態に保てます。
const compose = (f, g) => x => f(g(x));
const square = x => x * x;
const negate = x => -x;
const negativeSquare = compose(negate, square);
console.log(negativeSquare(4));なぜ合成するのか
合成を使うと、各関数の役割を絞って再利用でき、ネストした呼び出しの煩雑さを取り除けます。コードのあちこちにf(g(h(x)))を書く代わりに、名前を付けたパイプラインを一度作成して再利用できます。
const compose = (f, g) => x => f(g(x));
const toCents = d => Math.round(d * 100);
const addLabel = c => c + ' cents';
const priceLabel = compose(addLabel, toCents);
console.log(priceLabel(2.5));合成とカリー化の組み合わせ
カリー化された関数は、1引数関数を返すため、合成が想定する形にぴったり合い、きれいに合成できます。
const compose = (f, g) => x => f(g(x));
const add = a => b => a + b;
const multiply = a => b => a * b;
const addThenDouble = compose(multiply(2), add(3));
console.log(addThenDouble(5));多くの関数へ
ここまでのcomposeは2つの関数を処理していました。実際の合成では、任意の数の関数を扱います。次のレッスンでは、reduceを使って汎用的なcomposeと、左から右へ処理する対応版のpipeを作成します。
const compose = (f, g) => x => f(g(x));
const a = x => x + 1;
const b = x => x * 2;
const c = x => x - 3;
const combined = compose(a, compose(b, c));
console.log(combined(10));理解度チェック
compose = (f, g) => x => f(g(x))のとき、doubleが2倍し、incrementが1を加える関数だとすると、compose(double, increment)(5)は何を返しますか。
まとめ:関数合成
関数を組み合わせる方法を学びました。
compose(f, g)(x)はf(g(x))と等しく、右から左へ評価されます。- 順序が重要です。合成は可換ではありません。
- 合成によって、関数を小さく、名前付きで、再利用可能な状態に保てます。
- カリー化された関数はきれいに合成できます。次は、任意の数の関数を扱えるよう一般化します。
よくある質問
「関数合成」レッスンは無料ですか?
はい。「関数合成」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、JavaScript Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 JavaScript Academyコースには全4レッスンが含まれています。
「関数合成」で何を学びますか?
小さな関数を組み合わせてパイプラインを作成します。 ブラウザで直接実行するハンズオンコードでJavaScript Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。
JavaScript Academyを始めるのに経験は必要ですか?
事前経験は必要ありません。CoddyKitのJavaScript Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン3/4です。
「関数合成」レッスンにはどのくらい時間がかかりますか?
ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。
このJavaScript Academyレッスンでコードを書いて実行できますか?
はい。すべてのJavaScript Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。