Loanパターンをモナドfor式で使えるようにしてみたよ

みんな大好きLoanパターンですが、複数のリソースを扱いたい時などネストが深くなってしまうのでちょっと困ってしまいます。

そこでLoanパターンをモナドfor式で使えるようにしてみました。

class Loan[T <: {def close()}] private (value: T) {

  def foreach[U](f: T => U): U = try {
    f(value)
  } finally {
    value.close()
  }  

}
object Loan {
  
  def apply[T <: {def close()}](value: T) = new Loan(value)
  
}

これによってfor式でシンプルな記述ができます。例えば次のような感じに。

object Main {
  
  def main(args: Array[String]) {
    import java.io._
    
    for {
      in     <- Loan(new FileInputStream("source.txt"))
      reader <- Loan(new InputStreamReader(in, "UTF-8"))
      buff   <- Loan(new BufferedReader(reader))
      out    <- Loan(new FileOutputStream("dest.txt"))
      writer <- Loan(new OutputStreamWriter(out, "UTF-8"))
    } {
      var line = buff.readLine()
      while (line != null) {
        writer.write(line)
        line = buff.readLine()
      }
    }
    
  }
  
}

ちょっと Java7 の try with resources みたいですね。

それにしても Scala の for式は便利です。

2011-07-01 00:07 追記

モナドではないよね、という至極まっとうな突っ込みを頂いたので表記を訂正。

たしかにモナドではないですね。