30分でわかる(かも知れない)Scala超々入門! (8/8)
作成:2013-01-10 08:30
更新:2013-01-10 08:30
更新:2013-01-10 08:30
■カリー化とは?
最後に、Scalaの大きな特徴の一つである「カリー化」について触れておきましょう。
複数の引数を持つメソッドの場合、常に「すべての引数を指定してメソッドを呼び出す」ということになります。何度も呼び出す場合、常にすべての引数を指定して、何回も呼び出しを行うことになります。が、例えば「1つ目の引数は常に同じ値。2つ目の値が違うだけ」というような場合、もっとうまいやり方があってもよさそうなものです。それが「カリー化」と呼ばれる手法です。
カリー化は、例えば2つの引数のあるメソッドがあったとき、「1つ目の引数だけ」のメソッドに、「2つ目の引数を指定した関数を返す」ことで全体の処理が行えるようにする手法です。
これは、実物を見たほうが早いでしょう。まず、簡単なサンプルを挙げておきましょう。
カリー化は、すぐに理解しないとScalaが使えない!というものではありませんが、Scalaの柔軟さを示すものとして、その考え方と基本的な書き方はぜひ覚えておきたいところです。
――この他にも、Scalaには重要な機能がたくさんあるのですが、「とりあえずPlay Frameworkでスクリプトを書いたりできればいい」ということならば、ここまでの説明が頭に入っていれば十分でしょう。その他のことは、必要に応じて随時補足していくことにします。では、次回からいよいよPlay Frameworkの説明に入りましょう!
複数の引数を持つメソッドの場合、常に「すべての引数を指定してメソッドを呼び出す」ということになります。何度も呼び出す場合、常にすべての引数を指定して、何回も呼び出しを行うことになります。が、例えば「1つ目の引数は常に同じ値。2つ目の値が違うだけ」というような場合、もっとうまいやり方があってもよさそうなものです。それが「カリー化」と呼ばれる手法です。
カリー化は、例えば2つの引数のあるメソッドがあったとき、「1つ目の引数だけ」のメソッドに、「2つ目の引数を指定した関数を返す」ことで全体の処理が行えるようにする手法です。
これは、実物を見たほうが早いでしょう。まず、簡単なサンプルを挙げておきましょう。
object myapp {毎度登場した、totalメソッドの例です。引数を2つにし、最小値と最大値を指定して、その間の整数の合計を計算するようにしてみました。これ、例えば「0~100まで」「0~200まで」というように、第1引数の最小値が同じで最大値だけが違う、というような利用の仕方ができればけっこう便利ですね。――そこでカリー化です。
def main(args: Array[String]) = {
println("100から200までの合計:" + total(100, 200))
}
def total(min: Int, max: Int) = {
var res:Int = 0
for(n:Int <- Range(min,max + 1))
res += n
res
}
}
object myapp {なんだか不思議な形になりましたね。ここではcurryTotalというメソッドを定義してあります。これは、以下のようになっています。
def main(args: Array[String]) = {
val curryobj = curryTotal(100)
println("100から200までの合計:" + curryobj(200))
println("100から500までの合計:" + curryobj(500))
println("100から1000までの合計:" + curryobj(1000))
}
def curryTotal(min: Int) = (max: Int) => {
var res:Int = 0
for(n:Int <- Range(min,max + 1))
res += n
res
}
}
def curryTotal(min: Int) = (max: Int) => ……処理……curryTotal(min: Int)に、(max: Int)の関数オブジェクトが設定されているような形になっていますね。そしてこれを利用する側では、まず、
val curryobj = curryTotal(100)としてcurryobjに値を代入しています。これで、curryobjには、(max: Int)の関数オブジェクトが代入された形になります。後はこの定数curryobjを使い、
println("100から200までの合計:" + curryobj(200))こんな具合に、最大値だけをいろいろと指定して呼び出し処理すればいい、というわけです。もし、両方の引数を指定して利用したければ、
println("100から500までの合計:" + curryobj(500))
println("100から1000までの合計:" + curryobj(1000))
curryTotal(0)(50)こんな具合にして引数をしていすれば、最小値と最大値をまとめて指定し呼び出すこともできます。どちらのやり方も行えるのがカリー化の利点です。
カリー化は、すぐに理解しないとScalaが使えない!というものではありませんが、Scalaの柔軟さを示すものとして、その考え方と基本的な書き方はぜひ覚えておきたいところです。
――この他にも、Scalaには重要な機能がたくさんあるのですが、「とりあえずPlay Frameworkでスクリプトを書いたりできればいい」ということならば、ここまでの説明が頭に入っていれば十分でしょう。その他のことは、必要に応じて随時補足していくことにします。では、次回からいよいよPlay Frameworkの説明に入りましょう!
(by. SYODA-Tuyano.)
※プログラムリストが表示されない場合
AddBlockなどの広告ブロックツールがONになっていると、プログラムリスト等が表示されない場合があります。これらのツールをOFFにしてみてください。
●プログラム・リスト●
●リスト1――カリー化する前の例 object myapp { def main(args: Array[String]) = { println("100から200までの合計:" + total(100, 200)) } def total(min: Int, max: Int) = { var res:Int = 0 for(n:Int <- Range(min,max + 1)) res += n res } } ●リスト2――カリー化した例 object myapp { def main(args: Array[String]) = { val curryobj = curryTotal(100) println("100から200までの合計:" + curryobj(200)) println("100から500までの合計:" + curryobj(500)) println("100から1000までの合計:" + curryobj(1000)) } def curryTotal(min: Int) = (max: Int) => { var res:Int = 0 for(n:Int <- Range(min,max + 1)) res += n res } }
※関連コンテンツ