600000007

プログラムと折り紙のブログです。

‎Scala by Example‎ -> 5.2 カリー化 (Currying) 詳解

Scala by Example‎ -> 5.2 カリー化 (Currying)にて、ちょっと悩んだところを細かく読み解いてみました。

カリー化とは?

Wikipediaによると、

f( a, b ) = c という関数 f があるときに、F( a ) = g ただし、g( b ) = c という関数 g が得られる関数 F を定義した場合、F は、f をカリー化したものである。

というものだそうです。

具体的な数式を考えてみます。

f(x,y) = x + y 

という関数を考えます。そのとき、F()、g()を以下のように定義すると、Fはfのカリー化になります。…よね?

F(x) = x + g(y)
g(y) = y

以下のように式変形することができます。

f(x,y) = F(x)(y)                  ・・・ F(x)という関数の戻り値(関数)に引数yを渡す
     = (x + g(y)) (y)   ・・・F(x)の戻り値は関数(x + g(y))で、引数yを受け取る
     = x + g(y)       ・・・関数(x + g(y))を展開
     = x + y                    ・・・関数g(y)を展開

数論風記法とプログラム風記法がごっちゃになっている気がします・・・。
引数を渡しているのか、単純なかけ算をしているのか見分けがつきません。空気を読んで判断するものなのでしょうか?


やっと本題へ。

式を丁寧に展開してみる

def sumInts = sum(x => x)

def sumInts = sum(x => x)
           = sumF(a,b)
           = if (a > b) 0 else (a => a) + sumF(a + 1, b)
           = if (a > b) 0 else  a + sumF(a + 1, b)

def sumSquares = sum(x => x * x)

def sumSquares = sum(x => x * x)
              = sumF(a,b)
              = if (a > b) 0 else (a => a * a) + sumF(a + 1, b)
              = if (a > b) 0 else a*a + sumF(a + 1, b)

def sumPowersOfTwo = sum(powerOfTwo)

def sumPowersOfTwo = sum(powerOfTwo)
                    = sumF(a,b)
                    = if (a > b) 0 else powerOfTow(a) + sumF(a + 1, b)

それぞれ確かにScala by Example‎ -> 第 5 章 第一級の関数にあるsumInts、sumSquares、sumPowersOfTowと同じ物になっていますね。