微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

样本Simple IO Type如何摆脱“FP in Scala”中的副作用?

我正在阅读第13.2.1节,并且遇到了可以处理IO输入并在此期间摆脱副作用的示例:

object IO extends Monad[IO] {
  def unit[A](a: => A): IO[A] = new IO[A] { def run = a }
  def flatMap[A,B](fa: IO[A])(f: A => IO[B]) = fa flatMap f
  def apply[A](a: => A): IO[A] = unit(a)    
}

def ReadLine: IO[String] = IO { readLine }
def PrintLine(msg: String): IO[Unit] = IO { println(msg) }

def converter: IO[Unit] = for {
  _ <- PrintLine("Enter a temperature in degrees Fahrenheit: ")
  d <- ReadLine.map(_.todouble)
  _ <- PrintLine(fahrenheitToCelsius(d).toString)
} yield ()

关于这段代码,我有几个问题:

>在单位函数中,def run = a真的有用吗?
>在ReadLine函数中,IO {readLine}实际上做了什么?它真的会执行println函数还是只返回IO类型?
> for for comprehension中的_是什么意思(_< - PrintLine(“以华氏度为单位输入温度:”))?
>为什么它会消除IO副作用?我看到这些功能仍然与输入和输出相互作用.

解决方法

> IO的定义如下:

trait IO { def run: Unit }

根据该定义,您可以理解编写新IO [A] {def run = a}意味着从您的特征初始化匿名类,并将a指定为调用IO.run时运行的方法.因为a是by name parameter,所以在创建时实际上没有任何内容.
> Scala中遵循apply方法契约的任何对象或类都可以称为:ClassName(args),编译器将在对象/类上搜索apply方法并将其转换为ClassName.apply(args) )打电话.更详细的答案can be found here.因此,因为IO伴侣对象拥有这样一种方法

def apply[A](a: => A): IO[A] = unit(a)

允许扩张.因此我们实际上调用了IO.apply(readLine).
> _ has many overloaded uses in Scala.此事件意味着“我不关心从PrintLine返回的值,丢弃它”.这是因为返回的值是type Unit,我们与之无关.
>并不是IO数据类型删除了执行IO的部分,而是它将它推迟到以后的某个时间点.我们通常说IO在Main方法中运行应用程序的“边缘”.这些与外部世界的交互仍然会发生,但由于我们将它们封装在IO中,我们可以将它们作为我们程序中的值进行推理,这带来了很多好处.例如,我们现在可以组成副作用并依赖于其执行的成功/失败.我们可以模拟这些IO效果(using other data types such as Const),以及许多其他令人惊讶的好的属性.

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐