This is a followup to <a href="https://stackoverflow.com/questions/7404495/help-me-understand-this-scala-code-scalaz-io-monad">this</a> question.
Here's the code I'm trying to understand (it's from <a href="http://apocalisp.wordpress.com/2010/10/17/scalaz-tutorial-enumeration-based-io-with-iteratees/" rel="nofollow noreferrer">http://apocalisp.wordpress.com/2010/10/17/scalaz-tutorial-enumeration-based-io-with-iteratees/</a>):
This code is used like this (I'm assuming an
is implied)
I'm now trying to understand the
definition. Here's how I understand it. This is a <a href="http://scalaz.github.com/scalaz/scalaz-2.9.1-6.0.2/doc/index.html#scalaz.Monad" rel="nofollow noreferrer">scalaz.Monad</a>, so it needs to define
and
abstract values of the
trait.
takes a value and turns it into a value contained in the "container" type. For example it could take an
and return a
. This seems pretty simple.
takes a "container" type and a function that maps the type that the container holds to another type. The value that is returned is the same container type, but it's now holding a new type. An example would be taking a
and mapping it to a
using a function that maps
s to
s. Is
pretty much the same as
?
The implementation of
is where I'm stuck. Here's the code:
This definition takes
and maps it to
using a function that takes an
and returns an
. I guess to do this, it has to use
to "flatten" the result (correct?).
The
is the same as
I think?
the
method looks for an implicit value (value, right?) that implements
. Where does this implicit definition come from? I'm guessing this is from the
definition, but we're inside that definition right now and things get a little circular and my brain starts to get stuck in an infinite loop 
Also, the first argument to
(
) seems to be a function that takes no parameters and returns a.unsafePerformIO. How should I read this?
takes a container type as its first argument, so maybe
resolves to a container type?
Here's the code I'm trying to understand (it's from <a href="http://apocalisp.wordpress.com/2010/10/17/scalaz-tutorial-enumeration-based-io-with-iteratees/" rel="nofollow noreferrer">http://apocalisp.wordpress.com/2010/10/17/scalaz-tutorial-enumeration-based-io-with-iteratees/</a>):
Code:
object io {
sealed trait IO[A] {
def unsafePerformIO: A
}
object IO {
def apply[A](a: => A): IO[A] = new IO[A] {
def unsafePerformIO = a
}
}
implicit val IOMonad = new Monad[IO] {
def pure[A](a: => A): IO[A] = IO(a)
def bind[A,B](a: IO[A], f: A => IO[B]): IO[B] = IO {
implicitly[Monad[Function0]].bind(() => a.unsafePerformIO,
(x:A) => () => f(x).unsafePerformIO)()
}
}
}
This code is used like this (I'm assuming an
Code:
import io._
Code:
def bufferFile(f: File) = IO { new BufferedReader(new FileReader(f)) }
def closeReader(r: Reader) = IO { r.close }
def bracket[A,B,C](init: IO[A], fin: A => IO[B], body: A => IO[C]): IO[C] = for { a <- init
c <- body(a)
_ <- fin(a) } yield c
def enumFile[A](f: File, i: IterV[String, A]): IO[IterV[String, A]] = bracket(bufferFile(f),
closeReader(_:BufferedReader),
enumReader(_:BufferedReader, i))
I'm now trying to understand the
Code:
implicit val IOMonad
Code:
pure
Code:
bind
Code:
scalaz.Monad
Code:
pure
Code:
Int
Code:
List[Int]
Code:
bind
Code:
List[Int]
Code:
List[String]
Code:
Int
Code:
String
Code:
bind
Code:
map
The implementation of
Code:
bind
Code:
def bind[A,B](a: IO[A], f: A => IO[B]): IO[B] = IO {
implicitly[Monad[Function0]].bind(() => a.unsafePerformIO,
(x:A) => () => f(x).unsafePerformIO)()
}
This definition takes
Code:
IO[A]
Code:
IO[B]
Code:
A
Code:
IO[B]
Code:
flatMap
The
Code:
= IO { ... }
Code:
= new IO[A] {
def unsafePerformIO = implicitly[Monad[Function0]].bind(() => a.unsafePerformIO,
(x:A) => () => f(x).unsafePerformIO)()
}
}
I think?
the
Code:
implicitly
Code:
Monad[Function0]
Code:
implicit val IOMonad = new Monad[IO] {...}
Also, the first argument to
Code:
bind
Code:
() => a.unsafePerformIO
Code:
bind
Code:
() => a.unsafePerformIO