帮助我理解这段 Scala 代码:scalaz IO Monad
这是我试图理解的代码(来自 http://apocalisp.wordpress.com/2010/10/17/scalaz-tutorial-enumeration-based-io-with-iteratees/):
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)()
}
}
}
这段代码是这样使用的(我假设隐含了 import io._
)
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))
让我们从 bufferFile
定义开始。我认为调用 io.IO 的 apply
方法是否正确?该 apply
方法采用一个返回值的无参数函数(正确吗?)。我想这就是我被困住的地方。有人可以解释一下 bufferFile 的定义是如何工作的吗?
Here's the code I'm trying to understand (it's from http://apocalisp.wordpress.com/2010/10/17/scalaz-tutorial-enumeration-based-io-with-iteratees/):
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 import io._
is implied)
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))
Let's start with the bufferFile
definition. Am I correct in thinking that the apply
method of io.IO is called? That apply
method takes a parameterless function that returns a value (correct?). I guess this is where I'm stuck. Can someone explain how the definition of bufferFile
works?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
是的,你是对的,差不多;
io.IO.apply
使用所谓的“按名称”参数调用,该参数基本上是一个不接受任何内容 (Unit
) 并返回A
的函数>。最酷的事情是,当您像new BufferedReader(new FileReader(f))
一样直接传递A
实例时,它将被转换为类似( )=>新的 BufferedReader(新的 FileReader(f))
。作为
apply
的结果,您将获得一个IO[BufferedReader]
的实例,它定义了一个def unsafePerformIO
方法,该方法仅返回捕获的实例BufferedReader
。Yes you are right, well almost;
io.IO.apply
gets called with a so called "by name" parameter which is basically a function which takes nothing (Unit
) and returnsA
. The cool thing about is that when you pass an instance ofA
directly likenew BufferedReader(new FileReader(f))
, it will be converted to something like() => new BufferedReader(new FileReader(f))
.As a result of
apply
you get an instance of anIO[BufferedReader]
which defines a methoddef unsafePerformIO
which simply returns the instance of the capturedBufferedReader
.补充 agilesteel 的 答案,代码
相当于
Complementing agilesteel's answer, the code
Is equivalent to