Scalaでカリー化する

時代は関数型言語ということで、
関数型言語をはじめましたが、
Scalaの場合、基本的にJavaみたいな書き方で全然使える。


しかし、せっかく関数型言語なので、特有の機能を試してみた。
そして、名前の変なカリー化というのを勉強した。(はじめは意味がまったくわからなかったが。。)


個人的な結論として、カリー化は、高階関数があってのカリー化なんだと思う。
普通の言語では、引数がいくつかとれる関数・メソッドも、そのいくつかの引数は結局はセットで使われてる。
実際、多くの言語で、引数の( )括弧が必要とされる。
def hoge(a, b, c){
a+b+c
}


この関数をカリー化するというのは、これを
def hoge(a)(b)(c){
a+b+c
}


とかけるということのよう。


ここで大事なのは、見た目は似てる(使うようになると便利)が
hoge(a,b,c)は、aの値、bの値、cの値、から得られた結果を返します、というだけの意味だけど
hoge(a)(b)(c)は、hoge(a)_ の返したhoge(a)関数オブジェクトに、引数bを適応して、その結果のhoge(a)(b)関数オブジェクトに、引数cを適応した結果を返すという、非常に長い意味を持っている。 (Scalaでは、一番初めに関数オブジェクトを作るときに、最後にアンダーバーが必要なようだ。私間違ってませんよ!、関数オブジェクト作りたいんですよ!という主張でしょうか。)


そのおかげで、
hoge(1)_
という、a=1だけとりあえず決めました、という関数をつくることができる。(Scalaではhoge(1)だと引数たりずにエラー)
hoge(1)_が関数というのは、hogeという関数が、関数を返していることに他ならない (こういうhoge高階関数というそう)


要は、簡単に、少しだけ違う関数が作成できる。


たしかに、これまでは、どれくらい普遍的な関数を書こうか?とかなやんでいたけど、
できるだけ普遍的な(カリー化した)関数を書いておいて、
使いたいときに、すこしだけ具体的な関数を作ればよいのか。



コード例

object test {
def hoge(a:Int, b:Int, c:Int) :Int = {
a + b + c
}

def curriedhoge(a:Int)(b:Int)(c:Int) :Int = {
a + b + c
}

def main(args : Array[String]) : Unit = {
println( hoge(1,3,5) )

println( curriedhoge(1)(3)(5))

val tmp_fun = curriedhoge(1)_
println(tmp_fun(3)(5))
val tmp_fun2 = tmp_fun(3)
println(tmp_fun2(5))
}
}

すべて、9を返します。