カリー化
同じ引数を、毎回書いている
税込み価格を出す関数を addTax(price, rate) の形で作ったとします。呼ぶ側は毎回 addTax(price, 0.1) と書きます。20 か所で呼んでいれば 0.1 が 20 回並び、税率が変わったら 20 か所を直します。
配列にまとめてかけたいときも、そのままでは渡せません。
JavaScript
prices.map(price => addTax(price, 0.1));この price => ... は、0.1 を渡すためだけに書いた包み紙です。中身のある処理は 1 つも増えていないのに、行だけが増えています。
先に決めておいて、後で残りを渡す
2 つの引数を同時に受け取るのをやめます。先に決まる方だけを受け取り、残りを受け取る関数を返す形にすると、設定を 1 回で済ませられます。
JavaScript
const taxAdder = (rate) => (price) => Math.round(price * (1 + rate));
const addJpTax = taxAdder(0.1);
addJpTax(980); // 1078
prices.map(addJpTax); // 包み紙が要らないtaxAdder(0.1) が返した関数は、0.1 を覚えたままです。関数が、作られたときの外側の変数を覚えている性質をクロージャと呼びます。この覚えておく仕組みがあるので、設定と入力を別のタイミングで渡せます。
先に受け取る引数は、変わりにくいものを選びます。税率は画面が変わっても同じですが、価格は 1 件ごとに変わります。変わりにくい方を先に置くと、作った関数を長く使い回せます。逆にすると毎回作り直すことになり、包み紙を書いていたときと手間が変わりません。
相性が良いのは「最初に 1 回決めて、あとは何度も使う値」です。税率のほかに、区切り文字、ログの接頭辞、通貨記号、切り上げの桁などが当てはまります。csvLine と tsvLine のように、区切り文字だけ違う関数を 2 本作る、といった使い方もできます。
呼び出しが 2 段階になる
この形にすると、呼び出しの括弧が 2 つ続きます。設定を先に渡してから値を渡すので、まとめて書けば taxAdder(0.1)(980) です。見慣れないうちは、この見た目でつまずきます。
よくある間違いは、1 段目で止めて結果を使おうとすることです。taxAdder(0.1) の中身は数値ではなく関数なので、そのまま足したり比べたりしても、期待した値にはなりません。テストの結果に function や <function ...> という文字が出てきたら、括弧が 1 つ足りていないと思ってください。
逆に、設定を渡さずにいきなり値を渡すのも同じ間違いです。1 段目が受け取るのは設定で、値ではありません。どちらの引数が先に決まるのかを決めてから書き始めると、この取り違えは起きません。
覚え方 ... 括弧が 2 つ続いたら「先に設定、後でデータ」。順番を決めるのは、どちらが先に決まるか。
要件
- 関数の中で curriedAdd のような関数を定義し、curriedAdd(a)(b) の形で呼び出す
- curriedAdd(x) は (y) => x + y のような関数を返すこと
- 戻り値は整数。式は a + b と等価
入出力例
curriedAddAndApply(3, 4) → 7
curriedAddAndApply(0, 0) → 0
curriedAddAndApply(10, 5) → 15
curriedAddAndApply(-2, 5) → 3
curriedAddAndApply(100, 200) → 300
curriedAddAndApply(-5, -3) → -8