Skip to content

Instantly share code, notes, and snippets.

@rby
Created December 9, 2010 07:01
Show Gist options
  • Save rby/734431 to your computer and use it in GitHub Desktop.
Save rby/734431 to your computer and use it in GitHub Desktop.
Autoclose with for comprehensions
object closable {
type Closable = { def close }
class Autoclose[A <: Closable](c: A){
def foreach(f: A => Unit) = {
try { f(c) }finally { c.close }
}
}
case class Connection(name:String) {
def close = println("closing " + this)
}
case class Statement(c: Connection,q :String){
def close = println("closing " + this)
def exec = println("executing " + q + " on " + c)
}
implicit def autoClosable[A <: Closable](c: A) = new Autoclose(c)
def test = for(c <- Connection("conn");
st <- Statement(c,"select * from table")){
st.exec
}
}
-- execution
scala> closable.test
closable.test
executing select * from table on Connection(conn)
closing Statement(Connection(conn),select * from table)
closing Connection(conn)
@vpatryshev
Copy link

That's amazing. Monad in the box. Beautiful.

It's a pity that to generalize it to any side effect it would probably require dependent types; and this specific examples with close() demonstrates the trick better, but I wonder if we could generalize it to any post-action... it looks pretty similar to state monad.

Thanks anyway; it was an eye-opener to me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment