scalaで高階関数を学ぶ
scalaで関数を学ぶ
今日は 関数
関数
scalaでは関数もオブジェクト。
メソッドと関数は異なるらしい。
本来はdefで始まる構文で定義されたものだけがメソッド。 関数オブジェクトを関数と呼ぶ。 便宜上、メソッドも関数と呼ぶことがある。
こんな感じ。
scalaでは無名関数の宣言をカジュアルに行える。以下みたいに
// オブジェクト名: 引数型 => 戻り値型 = 引数名 => 処理 val f: String => Int = argValue => argValue.toInt * 2
と書けば無名関数の宣言と同時に変数に代入できる。
高階関数
関数を引数に取ったり関数を返すメソッドや関数のことを高階関数と呼ぶ。
以下の例みたいに、外から値と関数を渡して実行できる。
// 宣言 scala> def double(n: Int, f: Int => Int): Int = { | f(f(n)) | } double: (n: Int, f: Int => Int)Int // 実行 scala> double(1, m => m * 2) res4: Int = 4
この例はintを返しているけど、関数を返すこともできるっぽい。
全然読めなかった高階関数の宣言
以下の関数はドキュメントからそのまま持ってきたものである。
scala> import scala.io.Source import scala.io.Source scala> def withFile[A](filename: String)(f: Source => A): A = { | val s = Source.fromFile(filename) | try { | f(s) | } finally { | s.close() | } | } withFile: [A](filename: String)(f: scala.io.Source => A)A
引数が (引数1)(引数2)
となっている。
これまで書いてきた、C, PHP, RubyではこのSyntaxを見たことがなかったので戸惑った。
これを読む感じだとカリー化っぽいね。
ということでカリー化と同時実行の両方をやってみた。
ioで使うファイルはこれ
$ cat hoge hogepiyohuga
さて、色々試してみよう
scala> def withFile[A](filename: String)(f: Source => A): A = { | val s = Source.fromFile(filename) | try { | f(s) | } finally { | s.close() | } | } // -- カリー化 -- // fにファイル名だけ固定した関数を代入 scala> val f = withFile[String]("hoge")_ f: (scala.io.Source => String) => String = $$Lambda$917/0x000000080061c840@5896cb9c // 関数内で使われる関数を宣言 scala> val ff: Source => String = s => s.getLines.mkString ff: scala.io.Source => String = $$Lambda$920/0x0000000800629040@1de30c31 // hogeの中身を読み取って ffが実行される scala> f(ff) res3: String = hogepiyohuga // -- 同時実行 -- // filenameと実行関数を同時に渡す scala> val f = withFile[String]("hoge")(ff) f: String = hogepiyohuga
そこそこ理解できた。今日はこれで