帮助我理解这段 Scala 代码:scalaz IO Monad

发布于 2024-12-04 03:52:09 字数 1452 浏览 1 评论 0原文

这是我试图理解的代码(来自 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

泅人 2024-12-11 03:52:09

是的,你是对的,差不多; 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 returns A. The cool thing about is that when you pass an instance of A directly like new 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 an IO[BufferedReader] which defines a method def unsafePerformIO which simply returns the instance of the captured BufferedReader.

我为君王 2024-12-11 03:52:09

补充 agilesteel答案,代码

def bufferFile(f: File) = IO {   new BufferedReader(new FileReader(f)) }

相当于

def bufferFile(f: File) = new IO[A] {
  def unsafePerformIO = { new BufferedReader(new FileReader(f)) }
}

Complementing agilesteel's answer, the code

def bufferFile(f: File) = IO {   new BufferedReader(new FileReader(f)) }

Is equivalent to

def bufferFile(f: File) = new IO[A] {
  def unsafePerformIO = { new BufferedReader(new FileReader(f)) }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文