Blog#80: JavaScriptでカリー化パターンの理解

image.png

Bài viết này được mình dịch từ một bài viết tương tự của mình (Link tham khảo).

Để giúp các bạn có thể nâng cao trình độ tiếng Nhật, Blog này mình sẽ viết bằng tiếng Nhật.

Mục tiêu sẽ là, sử dụng Technical Document để học Tiếng Nhật. Mình sẽ cố gắng sử dụng ngữ pháp và từ vựng đơn giản nhất (tầm N4-N3) để giúp các bạn đọc nó dễ dàng hơn.


こんにちは、私は東京からのフルスタックWebデベロッパーであるTUANです。

今後の便利で面白い記事を見逃さないように、私のブログをフォローしてください。

関数型プログラミングでは、カリー化パターンは、関数を部分的に引数を適用することができるように書く方法です。 これは、元の関数が期待するいくつか、でもすべてではない、引数を提供することで新しい関数を作成できることを意味します。 これは、コードのさまざまな部分で再利用できるより具体的な関数を作成するために役立ちます。

カリー化とは何ですか?

カリー化とは、複数の引数を期待する関数を、それぞれ1つの引数だけを期待する関数のシーケンスに変換するプロセスです。 例えば、次の関数を考えてみましょう。この関数は、2つの数字を足し合わせます。

function add(x, y) {
  return x + y;
}

この関数をカリー化するには、最初の引数xを取る新しい関数を書き、2番目の引数yを期待する新しい関数を返すようにします。 このようにすることができます。

function add(x) {
  return function(y) {
    return x + y;
  }
}

今は、add(x, y)を呼び出すのではなく、add(x)(y)を呼び出すことができます。 これは、小さな変更に見えますが、いくつかの面白いことができるようになります。

カリー化の利点

カリー化パターンを使用するといくつかの利点があります。

1. 再利用可能な関数

カリー化の主な利点の1つは、コードのさまざまな部分で再利用できるより具体的な関数を作成できることです。 例えば、次の関数を考えてみましょう。この関数は、数字を10倍します。

function multiplyBy10(x) {
  return x * 10;
}

この関数は、10で乗算することに特化しているため、ほかの数字で乗算することはできません。 しかし、この関数をカリー化すると、どのような数字でも乗算することができるより一般的な関数を作成できます。

function multiply(x) {
  return function(y) {
    return x * y;
  }
}

const multiplyBy10 = multiply(10);
const multiplyBy5 = multiply(5);

この状態では、multiplyBy10およびmultiplyBy5という2つの特定の関数があり、コード全体で再利用できます。

2. 組み合わせ可能性

カリー化の利点のもう1つは、既存の関数から新しい関数を簡単に組み合わせることができることです。 例えば、次のような数字を加算および乗算する関数を考えてみます。

function add(x, y) {
  return x + y;
}

function multiply(x, y) {
  return x * y;
}

カリー化を使用して、2つの数字を乗算し、その結果に3番目の数字を加える新しい関数を作成することができます。

function add(x) {
  return function(y) {
    return x + y;
  }
}

function multiply(x) {
  return function(y) {
    return x * y;
  }
}

const multiplyAndAdd = x => y => z => add(multiply(x)(y))(z);

現在、計算(2 * 3) + 4を実行するには、multiplyAndAdd(2)(3)(4)を呼び出すことができます。

JavaScriptでのカリー化のリアルワールドの例

カリー化の基礎とその利点を学んだので、JavaScriptのコードでこのパターンを使用する方法のいくつかのリアルワールドの例を見てみましょう。

1. 部分的関数適用

カリー化のよくある使用法は、いくつかの引数が事前に埋められた新しい関数を作成することです。 これを部分的関数適用と呼びます。

例えば、次の関数を考えてみます。この関数は、税込みの合計金額を計算します。

function calculateTotal(price, taxRate) {
  return price + (price * taxRate);
}

特定の税率で注文の合計コストを計算する新しい関数を作成したい場合、カリー化を使用してこれを行うことができます。

function calculateTotal(price) {
  return function(taxRate) {
    return price + (price * taxRate);
  }
}

const calculateTotalWithTax = calculateTotal(0.08);

現在、価格が$100であり、税率が8%である注文の合計コストを取得するには、calculateTotalWithTax(100)を呼び出すことができます。

2. 高階関数の作成

カリー化のよくある使用法は、他の関数を引数として受け取るか、それらを出力として返す関数である高階関数を作成することです。

例えば、次の関数を考えてみます。この関数は、数値の配列とコールバック関数を受け取り、コールバック関数が各要素に適用された新しい配列を返します。

function map(array, callback) {
  const newArray = [];
  for (const element of array) {
    newArray.push(callback(element));
  }
  return newArray;
}

カリー化を使用して、コールバック引数が事前に埋められた新しい関数を作成することができます。

function map(callback) {
  return function(array) {
    const newArray = [];
    for (const element of array) {
      newArray.push(callback(element));
    }
    return newArray;
  }
}

const mapWithMultiplyBy2 = map(x => x * 2);

現在、mapWithMultiplyBy2([1, 2, 3])を呼び出すことで、配列[2, 4, 6]を取得することができます。

3. イベントハンドラーの作成

カリー化は、Reactやその他のJavaScriptライブラリでイベントハンドラーを作成するのにも役立つことがあります。

例えば、次の関数を考えてみます。この関数は、ボタンのクリックイベントを処理します。

function handleClick(event, id, name) {
  console.log(`Button ${id} with name ${name} was clicked!`);
  // Do something with `event`
}

カリー化を使用して、idname引数が事前に埋められた新しい関数を作成することができます。

function handleClick(id, name) {
  return function(event) {
    console.log(`Button ${id} with name ${name} was clicked!`);
    // Do something with `event`
  }
}

const handleClickWithIdAndName = handleClick(1, 'Submit Button');

現在、onClickプロパティにhandleClickWithIdAndNameを渡すことで、ボタンがクリックされたときに適切なメッセージがログされるようになります。

4. カスタムイテレーターの作成

カリー化は、JavaScriptでカスタムイテレーターを作成するのにも役立つことがあります。

例えば、次の関数を考えてみます。この関数は、数値の配列を反復処理し、合計を返します。

function sum(array) {
  let total = 0;
  for (const element of array) {
    total += element;
  }
  return total;
}

カリー化を使用して、配列を反復処理し、各要素にコールバック関数を適用する新しい関数を作成することができます。

function iterate(callback) {
  return function(array) {
    let total = 0;
    for (const element of array) {
      total += callback(element);
    }
    return total;
  }
}

const sum = iterate(x => x + 1);

console.log('sum([1,2,3])', sum([1,2,3])) // 9

現在、sum([1, 2, 3])を呼び出すことで、配列[2, 3, 4]の合計を取得することができます。

結論

この記事では、JavaScriptでカリー化パターンがどのように使用され、より特定で再利用可能な関数を作成し、コードの可換性と可読性を向上させることができるかを学びました。また、このパターンが実際の状況でどのように適用されるかを示すいくつかの実用的な例も見てきました。カリー化は使い方を覚えるのに少し時間がかかるかもしれませんが、関数型プログラミングのワークフローで強力なツールになることができます。

いつものように、この記事を楽しんで新しいことを学んでいただけたと思います。

ありがとうございました。次の記事でお会いしましょう!

この記事が気に入ったら、いいねをして購読してサポートしてください。ありがとうございます。

NGUYỄN ANH TUẤN

Xin chào, mình là Tuấn, một kỹ sư phần mềm đang làm việc tại Tokyo. Đây là blog cá nhân nơi mình chia sẻ kiến thức và kinh nghiệm trong quá trình phát triển bản thân. Hy vọng blog sẽ là nguồn cảm hứng và động lực cho các bạn. Hãy cùng mình học hỏi và trưởng thành mỗi ngày nhé!

Đăng nhận xét

Mới hơn Cũ hơn