カーリー化ってどこで使うん????🧐
はじめに
NextJSにて、自作のWebアプリを作っているのですが
毎度、使用しているライブラリのコードリーディングで躓くことがあります.
自分の場合はカーリー化のリーディングが、未だにすんなり出来ません.
そもそも、カーリー化で書く意味がわかっていないので、今回はカーリー化の利点について触れていきたいと思います.
そもそもカーリー化とは何ぞや?
wikipediaからの引用ですが
だそうです.
これだけでは、意味不明なので簡単なサンプルコードで見ていきます.
const funcA = (a) => (b) => {
console.log(a)
console.log(b)
}
funcA('a')('b')
とても簡単なサンプルコードですが、
本来ならば、
const funcA = (a, b) => {
console.log(a)
console.log(b)
}
funcA('a', 'b')
と書くとこをあえてカーリー化で書いた形になります.
カーリー化お前本当にいるん...
先ほどのサンプルコードを見た手前、カーリー化を使用する意図が自分同様疑問に思っている方もいると思います.
そこで、ちょっとした利点を紹介していきます.
特定の引数を固定した新しい関数を作成
まずはサンプルコードです.
const incrementUnlimit = (max) => (count) => {
console.log(max, count)
count++;
if(count < max){
return count;
}else {
return '上限に到達'
}
}
const incrementUnlimit10 = incrementUnlimit(10)
console.log(incrementUnlimit10(8))
console.log(incrementUnlimit10(19))
const incrementUnlimitMinus4 = incrementUnlimit(-4)
console.log(incrementUnlimitMinus4(-6))
console.log(incrementUnlimitMinus4(-1))
これは、incrementUnlimit
関数から上限値を特定の値に決め打ちした関数を別に作成した形になります.
高階関数
こちらは、よくあるカーリー化の実践例だと思います.
まずはサンプルコードです.
const unaryFunc = (baseNum, unaryNum, func) => {
return func(baseNum, unaryNum);
}
const incrementFunc = (baseNum, incrementNum) => baseNum + incrementNum;
const decrementFunc = (baseNum, decrementNum) => baseNum - decrementNum;
const curriedFunc = (func) => (x) => (y) => unaryFunc(x, y, func);
const curriedIncrementFunc = curriedFunc(incrementFunc)
console.log(incrementFunc(3, 5))
これは、increment or decrementを選んで、増減の値も設定できるようにしている動作になります.
高階関数を用いることで上記のように実装ができるそうです.
※他にもあるそうですが、すぐには必要なさそうなので機会があれば書きます.
最後に
カーリー化はあくまでもコーディングのテクニック的なもので、個人的には敢えて書く必要性があるとは思っていません.
何故なら、同様の方法を別のコードで実現可能だからです.(コーディングの答えは1つじゃないことを再度認識した)
ただし、コードリーディングや今後OSSの開発に携わりたい方には理解が必須だと思います.
一度で理解できないこと、この記事で理解できない事があると思いますが様々な記事を読んだりすることで理解を深めていくと良いと思います.
Discussion
カリー化は不要だと思う。ってのを、4年前に書いておきましたが、なかなか広まらないですね。
そろそろカリー化という不要なコードは駆逐したい。変なテクニックが業界に蔓延してほしくないから。
JS どんな関数でも部分適用するpartial関数 #JavaScript - Qiita