Scalaでカリー化。「カリーか」って聞くと、あれしか想像できなかったのですが、なんとなく理解したというエントリ。
まず、このエントリを読む。
Scalaの関数部分適用とカリー化 - kyabの日記
関数型プログラミングの世界は奇妙な世界ですね。慣れてくると好きになるわけで。ジョジョに似てますねー。。いや、なんでもないです。
関数の部分適用ってどういう時に使えるのかな?って感じですが、カリー化は無名関数を渡す使い方は、リソース開放のために使えますね。それが下記の例。
scala勉強会第3回のことなど - scalaとか・・・から、
object Utility{ /** C#のusing文のパクリ * @tparam A closeという名前を持っているものならなんでも * @tparam B 2番目の引数の関数オブジェクトの戻り値の型(これもなんでもいい) * @param resource 最後にcloseを必ず呼ばないといけないオブジェクト * @param func 1つめの引数のオブジェクトを使用して行う処理 */ def using[A <: {def close()},B](resource:A)(func:A => B):Unit = { try{ func(resource) //処理実行 }catch{ case e:Exception => e.printStackTrace //エラーキャッチしたら、とりあえずログはいておく。(本当はこの部分の処理とか変える必要あるはず) }finally{ if(resource != null) resource.close() //エラーが起きても起きなくても、必ず最後にcloseを呼ぶ(close呼ぶことによって、さらに例外が発生するようなものの場合、さらに何らかの処理が必要ですが・・・(´・ω・`) ) } } }
C#でコード書くときはusingは普通に使うわけですが、Scalaではカリー化を使うと同じことができるわけです。まさに言語を拡張している気分。。
さらに型引数の
A <: {def close()}
の部分は、Scalaの静的型付けのダックタイピング?みたいなところがイケてますね。Aのcloseメソッドのシグニチャのみを指定できるという。Javaでは、Closeable#closeメソッドを使うことを想像するけど、Closeableの実装しかcloseできないということになるので、いろいろ姑息なことをしなくてはならん。例えばこんな感じ。
http://sourceforge.jp/projects/sisioh/svn/view/altair/non-bundle/sisioh-commons/trunk/src/main/java/org/sisioh/commons/utils/CloseableUtil.java?view=markup&root=sisioh
usingを呼び出す時は型引数を明示的に指定しなくても、型推論するらしい。これはいい。
scala勉強会第3回のことなど - scalaとか・・・から、
import Utility.using //例として、自分で定義したものをimport object JavaLikeDatabaseSelect { def main(args: Array[String]) = { Class.forName("org.postgresql.Driver") using(DriverManager.getConnection( "jdbc:postgresql://localhost/scaladb", "scalar", "scalar")){ db => val st = db.createStatement val sql = "SELECT id, name FROM sample" val res = st.executeQuery(sql) while(res.next){ val id = res.getInt(1) val name = res.getString(2) println(id+", "+name) } } } }