ソースを読み解く

サンプルにでていた

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
なのかーーー。

なるほど。わかったような。わからないような。