
高階関数とカリー化
関数型プログラミングを学んでいると必ず出てくる高階関数とカリー化について、学んでもすぐに忘れてしまうのでここにまとめておきます。
高階関数とは
高階関数とは、関数を引数に取る関数、または関数を返す関数のことです。
関数を引数にとる関数
JSの例を書きます。
mapはaddThreeという関数を引数に取り、arrの各要素に対して3を足す関数を実行しその結果を返しています。
function addThree(x) {
return x + 3;
}
const arr = [1,6,3,2];
arr.map(addThree);
関数を返す関数
下記が例となります。
addはyを引数に取り、x+yを返す関数を返す関数です。
add(2)が返すのは関数です。
よってaddTwo(3)という関数呼び出しによって5という値が返ります。
function add(x) {
return function(y) {
return x + y;
}
}
const addTwo = add(2);
addTwo(3);
カリー化
カリー化は引数をまとめて渡さずに関数を返す関数を作ることです。
上のaddは愚直に書くとこうなります。
function add(x, y) {
return x + y;
}
add(2, 3);
これを分けて書くと上の関数を返す関数で見た例のようになります。
function add(x) {
return function(y) {
return x + y;
}
}
add(2)(3);
カリー化の何が嬉しいのかは、普段関数型言語でプログラミングをしていない自分にはわからないため、GPTさんに聞いた回答を記載します。(mapやfilterを使うなど関数型っぽい書き方をすることはありますが)
コードの再利用性の向上: カリー化により、特定の引数を持つ関数のバリエーションを簡単に作成できます。これにより、コードの重複を減らし、再利用性を高めることができます。
関数の柔軟性の向上: カリー化された関数は、引数を部分的に適用することで、新しい関数を生成できます。これにより、より柔軟なコードの書き方が可能になり、さまざまなシナリオに対応しやすくなります。
関数の読みやすさと理解のしやすさの向上: カリー化を使用すると、関数の呼び出し方がシンプルになり、コードの意図が明確になります。これにより、コードの読みやすさと理解のしやすさが向上します。
遅延評価(Lazy Evaluation): カリー化は遅延評価をサポートする言語で特に有用です。関数の引数が実際に必要になるまで評価を遅らせることができるため、パフォーマンスの最適化に役立ちます。
関数合成の容易さ: カリー化を利用すると、小さな関数を組み合わせてより複雑な操作を行う「関数合成」が容易になります。これにより、モジュラーなコード設計が促進されます。
ポイントフリースタイル(Point-free style)の促進: カリー化は、ポイントフリースタイル(引数を明示的に指定しないコーディングスタイル)の実現を容易にします。これにより、コードがより宣言的になり、抽象度が高まります。
コードの再利用性や関数の柔軟性の向上、関数合成の容易さと言うのはなんとなくわかる気がしますね。
ただ繰り返し書く部分のロジックを他の関数に切り分ければ、再利用はできると思うので問題を難しくしているようにも見えてしまいます。
まとめ
カリー化の明確なメリットは自分はまだ納得できていないですが、概念として知っておいて損はないと思うのでとりあえず良しとしましょう。