scalaはファーストクラスの関数を定義できるが、valに代入してよく使われる。
defで定義されるものは関数とわけて考えるべきで、メソッドとよばれる。
func_a.scala
scala> val coneV = new Function2[Double, Double, Double] {
def apply(r: Double, h: Double) = (1.0/3.0) * Math.PI * r * r * h
}
scala> val v = coneV.apply(3, 7)
v: Double = 65.97344572538566
func_b.scala
scala> val coneV = (r:Double, h:Double) => (1.0/3.0) * Math.PI * r * r * h
coneV: (Double, Double) => Double = <function2>
scala> val v = coneV(3, 7)
v: Double = 65.97344572538566
上記はどちらもファーストクラス関数の例で、どちらも全く同じ意味となる。
func_aが正式な関数定義の例だが、シンタックスシュガーとしてfunc_bの記法が用意されていて、こっちのほうが頻出する。
Function2やは、scalaが標準で用意している型で、2つの引数を受け取る関数を表している。
coneV(3,7)
のようにメソッドをよべるのは実際にはapplyメソッドがよばれている。
ちなみに、標準でFunctionが受け付けられる引数は22個までらしい。
scala> val f = (aa:Int,ab:Int,ac:Int,ad:Int,ae:Int,af:Int,ag:Int,ah:Int,ba:Int,bb:Int,bc:Int,bd:Int,be:Int,bf:Int,bg:Int,bh:Int,ca:Int,cb:Int,cc:Int,cd:Int,ce:Int,cf:Int,cg:Int,ch:Int,da:Int,db:Int,dc:Int,dd:Int,de:Int,df:Int,dg:Int,dh:Int,ea:Int,eb:Int,ec:Int,ed:Int,ee:Int,ef:Int,eg:Int,eh:Int,fa:Int,fb:Int,fc:Int,fd:Int,fe:Int,ff:Int,fg:Int,fh:Int,ga:Int,gb:Int,gc:Int,gd:Int,ge:Int,gf:Int,gg:Int,gh:Int,ha:Int,hb:Int,hc:Int,hd:Int,he:Int,hf:Int,hg:Int,hh:Int) => aa+ab+ac+ad+ae+af+ag+ah+ba+bb+bc+bd+be+bf+bg+bh+ca+cb+cc+cd+ce+cf+cg+ch+da+db+dc+dd+de+df+dg+dh+ea+eb+ec+ed+ee+ef+eg+eh+fa+fb+fc+fd+fe+ff+fg+fh+ga+gb+gc+gd+ge+gf+gg+gh+ha+hb+hc+hd+he+hf+hg+hh
<console>:10: error: implementation restricts functions to 22 parameters