関数


Scalaの関数は他の言語の関数と扱いが異なります。Scalaの関数は単にFuntion0 ~ Function22までのトレイトの無名サブクラスのインスタンスです。

例えば、2つの整数を取って加算した値を返すadd関数は次のように定義できます。

val add = new Function2[Int, Int, Int] {
  def apply(x: Int, y: Int): Int = x + y
}

上述の方法での関数定義ではコードが冗長になりすぎます。そのため、ScalaではFunction0 ~ Function22までのトレイトのインスタンスを生成するためのシンタックスシュガーが用意されています。
このシンタックスシュガーを用いると先程のadd関数はこのようになります。

val add2 = (x: Int, y: Int) => x + y

この時add2には単に関数オブジェクトが入っているだけであり、関数本体には何の名前もついていません。
add2右辺のような定義をScalaでは無名関数と呼びます。

無名関数は単なるFunctionNオブジェクトですから、自由に変数や引数に代入したり戻り値を返すことができます。
このような、関数を自由に変数や引数に代入したり戻り値として返すことができる性質を指して、Scalaでは関数が第一級の値(First Class Object)であるといいます。

戻り値の型は通常関数本体の戻り値から推測されます。

Scalaの関数はFunction0 ~ Function22までのトレイトの無名サブクラスのインスタンスなので、引数の最大個数は22個となります。

定義した関数の型は、本来Function[...]のようにして記述しなければいけませんが、関数の型については特別にシンタックスシュガーが設けられています。一般に

(n1: N1, n2: N2, n3: N3, ... nn: NN) => B

となるような関数の型はFunctionN[N1, N2, N3, ..., NN, Bの型]と書く代わりに

(N1, N2, N3, ..., NN) => Bの型

として記述することができます。 この時引数が1つだけの場合は丸括弧を省略することができます。 この場合の関数の例をこのようになります。

val func: Int => Double = (x: Int) => n

この場合 引数の型 => 戻り値の型 = 引数の変数 => 関数本体
となります。また、引数の変数の型を省略して書くこともできます。

val func: Int => Doucle = x => n