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

はじめに

アロー関数は前提知識。

カリー化を一言

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

???????

カリー化の理論的な説明

  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で多出する()の連続が完璧に理解できるはずだ。

またメモではカリー化のメリットばかりを強調したが、何事においても銀の弾丸というものは存在しない。
キチンと用法・目的を明確にして使用しよう。

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

styled components documentation日本語訳②ーAdvancedー 代数的データ型Deep Dive in Scala ScalaのF[_]と高カインド型(Higher Kinded Type)を完全に理解していく
View Comments
There are currently no comments.