今回は「関数型言語」独特の「一人前の値としての関数」についてやっていこうかと思います。
「一人前の値」とは、数値や文字列のように、関数に引数として渡したり、他の関数から処理結果として受け取ったり、変数に格納できる値のことです。
要は、関数型言語では関数を値のようにやり取りすることができるわけなのです。今回は、そのやりかたを説明します。
普通の関数リテラルの書き方
上の関数でいう(x:Int,y:Int)が関数のとる引数で、x + yが関数の中身です。
中身が二行にわたる場合には=>以下を括弧でくくります。
関数リテラルの使い方はこんな感じです。
val numList = List(1,2,3,4,5) //1,2,3,4,5が入ってるリストを作成。
val inc = (x:Int) => x + 1 //1足す関数を値として定義
numList.map(inc) //numListの各要素にinc(1を足すという動作)を実行
println(numList.toString) //List(2,3,4,5,6)が出力される。
さて、関数リテラルについて一通り説明が終わりました。
しかし。この関数リテラルの書き方は少し冗長です。
実は関数リテラルの書き方は、実はこのように省略することができます。
/*正負を判定する関数*/
val isPlus = (x:Int) => x > 0 //お堅い書き方
val shorter_isPlus = (x) => x > 0 //型推論に頼った書き方
val shortest_isPlus = _ > 0//_(プレースホルダー)に頼った書き方
shortest_isPlusはプレースホルダーという、場所を用意していることを示す記号を使っていて、N個目に渡される引数がN番目の_に代入されます。
ここまでかいておいて何ですけど、
実はこのshorter_isPlusや、shortest_isPlusのような書き方をしてもエラーがでてしまいます。
原因はxの型を推論する材料がないからです。
ではこの構文たちはどう応用するか。やりかたをしたに挙げます。
val shotest_isPlus = (_:Int) + (_:Int) //プレースホルダーに型を指定してやる
val numList = List(1,2,3,4,5).map(_ + 1)//高階関数などあらかじめ型(今の場合はInt)が指定されている場合で使う
今回はこの辺で終わります。
次回は関数呼び出しの特殊な記法についてやります。