An example Scala program to copy data from one handle to another might
look like this:
def main(args: Array[String]) =
withFileInputStream("inFile.txt")(is =>
withFileOutputStream("outFile.txt")(os =>
copy(is, os)
)
)
// A hypothetical function for safely using a FileInputStreamdef withFileInputStream[A](path: String)(f: FileInputStream => IO[A]): IO[A]
// A hypothetical function for safely using a FileOutputStreamdef withFileOutputStream[A](path: String)(f: FileOutputStream => IO[A]): IO[A]
// A hypothetical function that copies data from an InputStream to an OutputStreamdef copy(is: InputStream, os: OutputStream): IO[Unit]
withFileInputStream and withFileOutputStream are a few of many functions
that acquire some resource in an exception-safe way. These functions take a
callback function as an argument and they invoke the callback on the resource
when it becomes available, guaranteeing that the resource is properly disposed
if the callback throws an exception. These functions usually have a type that
ends with the following pattern:
Callback
-------------
def withXXX[A](...)(f: R => IO[A]): IO[A]
Here are some examples other examples of this pattern:
Acquiring multiple resources in this way requires nesting callbacks.
However, you can wrap anything of the form A => IO[R] => IO[R] in the
Managed monad, which translates binds to callbacks for you:
An example Scala program to copy data from one handle to another might look like this:
withFileInputStream
andwithFileOutputStream
are a few of many functions that acquire some resource in an exception-safe way. These functions take a callback function as an argument and they invoke the callback on the resource when it becomes available, guaranteeing that the resource is properly disposed if the callback throws an exception. These functions usually have a type that ends with the following pattern:Here are some examples other examples of this pattern:
Acquiring multiple resources in this way requires nesting callbacks. However, you can wrap anything of the form
A => IO[R] => IO[R]
in theManaged
monad, which translates binds to callbacks for you: