ソースを読み解く
サンプルにでていた
def sum(f: Int => Int): (Int, Int) => Int = { def sumF(a: Int, b: Int): Int = if(a > b) 0 else f(a) + sumF(a + 1, b) sumF }
これを読み解く。
まず、
def sum(f: Int => Int): (Int, Int) => Int
sumって名前の関数を宣言している。
なぞなのは引数の
f: Int => Int
これは、匿名関数っぽい??
これは、名前渡し。
実際に値が入るまで評価を待つ。
やっぱ、匿名関数か?どっちだ??
JavaScriptでいうところの、関数の参照渡してるような
感じなのかな?
そして戻り値
(Int, Int) => Int
戻り値はInt型の引数2つでInt返す関数ってことかな?
ここではsumFが戻り値ってことだな。
中身のこれはsumFって関数を宣言してる
def sumF(a: Int, b: Int): Int = if(a > b) 0 else f(a) + sumF(a + 1, b)
で、ここで、sum()で渡したfが関数(?)として入ってる。
次の行の
sumF
で参照戻してあげてるんだろう。
では関数を実行。
sum(a => a + 2)(1, 2)
結果は『7』になる。
さっぱりなので、変数に数字を当てはめて追っていってみる。
def sumF(1, 2): Int = if(1 > 2) 0 else f(1) + sumF(1 + 1, 2) }
ifの評価はfalseになるからelse以降に注目。あと関数Fを展開する。
def sumF(1, 2): Int = (1 + 2) + sumF(1 + 1, 2) }
sumF(1 + 1, 2)を展開してみる
def sumF(2, 2): Int = if(2 > 2) 0 else f(2) + sumF(2 + 1, 2) }
sumF(2 + 1, 2)を展開してみる
def sumF(3, 2): Int = if(3 > 2) 0 else f(3) + sumF(3 + 1, 2) }
ここで0が返るので再帰が終わる。では順に戻ってみる。
sumF(2 + 1, 2)は0になるので置き換え。ついでにf(2)を展開
def sumF(2, 2): Int = if(2 > 2) 0 else (2 + 2) + 0 }
なので、sumF(1 + 1, 2)は4になるので置き換え
def sumF(1, 2): Int = (1 + 2) + 4 }
なので、結果が7
なのかーーー。
なるほど。わかったような。わからないような。