I wanted a very tiny example of using the IO Monad in the brilliant Scalaz library, and here it is.
I present the example without explanation, the web does not need another set of explanations about this subject but I have found the following blogs useful, with a mix of theoretical explanation and practical examples:
- Functional IO in Scala with Scalaz
- The IO Monad for People who Simply Don’t Care
- Towards an Effect System in Scala, Part 2: IO Monad
All this example does is print out the names of files in a directory.
import scalaz._ import Scalaz._ import scalaz.effects._ import java.io._ object TheIO extends App { val dirInIO = io { new File(System.getProperty("user.dir")) } def filesInIO = for (dir <- dirInIO) yield dir.listFiles() def namesInIO = for (theFiles ← filesInIO) yield theFiles.map(_.getName()) def printNamesInIO = for (all ← namesInIO) yield all.map(println(_)) val result = printNamesInIO println("Nothings happened yet, lets go!") result.unsafePerformIO } |
Mixing regular impure functions (such as println) with the effectful functions using IO monad is asking for trouble. You should wrap usage of impure functions with io or use their monadic counterparts.
For example: http://paste.pocoo.org/show/530040/.
Thanks
What sort of trouble is likely to arise?
Welcome.
In this case, none. The effects are easy to visualize for the small examples. Even though `printNamesInIo` uses an impure function, its type signature still tells the truth. So it’s perfectly fine. In more complex cases though, you may end up with functions whose type signatures lie (e.g. `IO[A]` instead of `IO[IO[A]]`, and thus lead to early execution of effects, and perhaps incorrect interleaving with other effects etc.
I am sorry I am unable to think of an example to support my point. When I come across one, I will let you know.
No worries, thanks for pondering it.