Skip to content

Instantly share code, notes, and snippets.

@x7c1
Last active April 29, 2017 17:49
Show Gist options
  • Select an option

  • Save x7c1/d0b26cd9236682481da6ebb8636b2f8a to your computer and use it in GitHub Desktop.

Select an option

Save x7c1/d0b26cd9236682481da6ebb8636b2f8a to your computer and use it in GitHub Desktop.
improve Close module
package continuation
import close.Closer
object Close {
def apply0[A: Closer](res: => A): Continuation0[A] =
Continuation0 { f =>
val target = res
try f(target)
finally implicitly[Closer[A]] close target
}
def apply[A: Closer](res: => A): Continuation2[A] =
Continuation2 apply new Callback[A] {
override def apply[R](f: A => R): R = {
val target = res
try f(target)
finally implicitly[Closer[A]] close target
}
}
}
package continuation
class Continuation0[+A] private(callback: (A => Unit) => Unit) {
def map[B](f: A => B): Continuation0[B] = Continuation0 {
g => apply(f andThen g)
}
def flatMap[B](f: A => Continuation0[B]): Continuation0[B] = Continuation0 {
g => apply(a => f(a) apply g)
}
def apply(f: A => Unit): Unit = callback(f)
def run(): Unit = callback(_ => ())
}
object Continuation0 {
def apply[A](f: (A => Unit) => Unit): Continuation0[A] = {
new Continuation0(f)
}
}
package continuation
trait Callback[A] {
def apply[R](f: A => R): R
}
class Continuation2[+A] private(callback: Callback[A]) {
def map[B](f: A => B): Continuation2[B] =
Continuation2 apply new Callback[B] {
override def apply[R](g: B => R): R = {
callback(f andThen g)
}
}
def flatMap[B](f: A => Continuation2[B]): Continuation2[B] =
Continuation2 apply new Callback[B] {
override def apply[R](g: B => R): R = {
callback(a => f(a) apply g)
}
}
def apply[R](f: A => R): R = callback(f)
def run(): A = apply(identity)
}
object Continuation2 {
def apply[A](f: Callback[A]): Continuation2[A] = {
new Continuation2(f)
}
}
package continuation
import java.io._
import close.Closer
object Main {
def main(args: Array[String]): Unit = {
implicit def closer[R <: Closeable]: Closer[R] = Closer { x =>
println(s"close: ${x.toString}")
x.close()
}
val a = for {
in <- Close(new FileInputStream(getClass.getResource("/source.txt").getPath))
reader <- Close(new InputStreamReader(in, "UTF-8"))
buff <- Close(new BufferedReader(reader))
out <- Close(new FileOutputStream("dest.txt"))
writer <- Close(new OutputStreamWriter(out, "UTF-8"))
} yield {
println("[begin]")
var line = buff.readLine()
while (line != null) {
println(line)
writer.write(line + "\n")
line = buff.readLine()
}
println("[end]")
"hello"
}
a.run()
println(a.run())// "hello" (`run` can return the last value of for-yield)
println("[single]")
Close(new FileInputStream(getClass.getResource("/source.txt").getPath)).apply(_ => ())
println("[end]")
}
}
@x7c1
Copy link
Author

x7c1 commented Apr 29, 2017

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