Posted at

サルでもわかるカリー化とそのメリット


はじめに

社内向けの教育資料を転載。

アロー関数は前提知識。


カリー化を一言


関数を返す関数によってプログラムの共通化を図り、堅牢で安全なプログラムを作る。

???????


カリー化の理論的な説明


  1. 複数変数を取る関数がある

  2. その関数を1変数を取り、関数を返す関数に分解する

or

wikipediaの説明

関数 f が {\displaystyle f:(X\times Y)\to Z} の形のとき、f をカリー化したものを g とすると、 g:X\to (Y\to Z) の形を取る

わからない?それがふつう

私も最初はチンプンカンプン


具体例


やりたいこと

2つの数を引数に受け取り、それらを足す関数addを定義したい


まずは普通に

普通に考えれば

const add = (x, y) => x + y

というふうになる。

使い方は、

add(1, 2)

// ⇛ 3

てな感じ。

ここではあえて動作を詳しく書いてみると、

1. addxyとして1と2を受け取る

2. 1+2が計算され3がreturn

という動作。

実にシンプル


カリー化してみる

上のaddをカリー化してみると、

const add = x => y => x + y

となる。

使い方は、

add(1)(2)

// ⇛ 3

というかたち。

動作を理解できるかな?

詳しく見てみよう。


  1. addはxを受け取る

  2. この瞬間xは1に化けるためadd(1)(y) => 1 + yという関数を返す


  3. add(1)から返ってきた関数に(2)というカッコがつくことになるので、ここでyが2に化ける


  4. 1+2が計算され3がreturn

どうだろう、理解できただろうか。

ここは重要なので必ず理解してほしい。

アロー関数の動作が曖昧な人は一度そこから調べる、実際にコンソールで試してみる、なんでもいいからやってみて理解の努力をしてほしい。

これらは書いてあるとおりに動くはずだ。

では、なぜこんなカリー化とかいう難解なものを使わなければいけないのであろうか?

同じことがカリー化を使用しなくても簡単に実現できるというのに。


カリー化のメリット


そもそもプログラミングで大事にしたいこと

一般にコードを書くときに共通化が大事だと言われる。

ではなぜ共通化が大事なのか?

それは同じ処理を何度も書きたくないからである。

それは単純にめんどくさいからでもあるし、またより重要なのは人間は同じことを何回も繰り返すと、間違える生き物である。

すなわちバグの温床なのだ。

だからこそ共通化が大事だと言われる。

ではここで様々な値に1を足すという操作を考えてみよう。


addをカリー化なしで実装した場合のユースケース

const add = (x, y) => x + y

add(1, 2)
// ⇛ 3

add(1, 3)
// ⇛ 4

add(1, 100)
// ⇛ 101

...

毎回第一引数に1を代入していることに気づいただろうか?

これは完全にムダであり、バグの温床だ。

ではカリー化を使ってリファクタリングしてみよう。


addをカリー化で実装した場合のユースケース

const add = x => (y) => x + y

const add1 = add(1)

add1(2)
// ⇛ 3

add1(3)
// ⇛ 4

add1(100)
// ⇛ 101

...

重複がなくなり、共通化された。

ムダなタイピング、バグからの開放である。


最後に

理解できただろうか?

一度では理解が難しいのが普通だと思う。

何度もこのメモを読んだり、実際に手を動かしたり、このメモについて周りの人と話してみたり、何でもいいからやってみよう。

いつかカリー化とjavascriptで多出する()の連続が完璧に理解できるはずだ。

またメモではカリー化のメリットばかりを強調したが、何事においても銀の弾丸というものは存在しない。

キチンと用法・目的を明確にして使用しよう。

君も今日からカリー化マスター!