样本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),以及许多其他令人惊讶的好的属性.

相关文章

共收录Twitter的14款开源软件,第1页Twitter的Emoji表情 Tw...
Java和Scala中关于==的区别Java:==比较两个变量本身的值,即...
本篇内容主要讲解“Scala怎么使用”,感兴趣的朋友不妨来看看...
这篇文章主要介绍“Scala是一种什么语言”,在日常操作中,相...
这篇文章主要介绍“Scala Trait怎么使用”,在日常操作中,相...
这篇文章主要介绍“Scala类型检查与模式匹配怎么使用”,在日...