I ran into this while using a PDF library, but there have been plenty of other occasions in which I would have something like this useful.
There are many situations in which you have a resource (that needs to be closed) and you use these resources for obtaining objects that are only valid as long as the resource is open and hasn't been released yet.
Let's say the b
reference in the code below is only valid while a is open:
val a = open()
try {
val b = a.someObject()
} finally {
a.close()
}
Now, this code is fine, but this code isn't:
val b = {
val a = open()
try {
a.someObject()
} finally {
a.close()
}
}
With that code I would have a reference to something of resource a, while a is no longer open.
Ideally I'd like to have something like this:
// Nothing producing an instance of A yet, but just capturing the way A needs
// to be opened.
a = Safe(open()) // Safe[A]
// Just building a function that opens a and extracts b, returning a Safe[B]
val b = a.map(_.someObject()) // Safe[B]
// Shouldn't compile since B is not safe to extract without being in the scope
// of an open A.
b.extract
// The c variable will hold something that is able to exist outside the scope of
// an open A.
val c = b.map(_.toString)
// So this should compile
c.extract