scala - 猫作家矢量是空的

标签 scala scala-cats

我编写了这个简单的程序,试图了解 Cats Writer 的工作原理

import cats.data.Writer
import cats.syntax.applicative._
import cats.syntax.writer._
import cats.instances.vector._

object WriterTest extends App {
   type Logged2[A] = Writer[Vector[String], A]
   Vector("started the program").tell
   val output1 = calculate1(10)
   val foo = new Foo()
   val output2 = foo.calculate2(20)
   val (log, sum) = (output1 + output2).pure[Logged2].run
   println(log)
   println(sum)

   def calculate1(x : Int) : Int = {
      Vector("came inside calculate1").tell
      val output = 10 + x
      Vector(s"Calculated value ${output}").tell
      output
   }
}

class Foo {
   def calculate2(x: Int) : Int = {
      Vector("came inside calculate 2").tell
      val output = 10 + x
      Vector(s"calculated ${output}").tell
      output
   }
}

该程序有效,输出为
> run-main WriterTest
[info] Compiling 1 Scala source to /Users/Cats/target/scala-2.11/classes...
[info] Running WriterTest 
Vector()
50
[success] Total time: 1 s, completed Jan 21, 2017 8:14:19 AM

但是为什么向量是空的?它不应该包含我使用“tell”方法的所有字符串吗?

最佳答案

当您调用 tell在您的 Vector 上s,每次创建 Writer[Vector[String], Unit] .但是,您实际上从未对您的 Writer 进行任何操作。 s,您只需丢弃它们。此外,您调用pure创建您的最终 Writer ,它只是创建了一个 Writer有一个空的 Vector .您必须将作家组合在一起,形成一条承载您的值(value)和信息的链条。

type Logged[A] = Writer[Vector[String], A]

val (log, sum) = (for {
  _ <- Vector("started the program").tell
  output1 <- calculate1(10)
  foo = new Foo()
  output2 <- foo.calculate2(20)
} yield output1 + output2).run

def calculate1(x: Int): Logged[Int] = for {
  _ <- Vector("came inside calculate1").tell
  output = 10 + x
  _ <- Vector(s"Calculated value ${output}").tell
} yield output

class Foo {
  def calculate2(x: Int): Logged[Int] = for {
    _ <- Vector("came inside calculate2").tell
    output = 10 + x
    _ <- Vector(s"calculated ${output}").tell
  } yield output
}

注意 for 的使用符号。 calculate1的定义是真的
def calculate1(x: Int): Logged[Int] = Vector("came inside calculate1").tell.flatMap { _ =>
  val output = 10 + x
  Vector(s"calculated ${output}").tell.map { _ => output }
}
flatMap是一元绑定(bind)操作,这意味着它了解如何获取两个一元值(在本例中为 Writer )并将它们连接在一起以获得一个新值。在这种情况下,它会生成 Writer包含日志的串联和右侧的值。

注意没有副作用。没有全局状态可用于 Writer可以记住您对 tell 的所有调用.你反而赚了很多 Writer s 并将它们与 flatMap 连接在一起最后得到一个大的。

关于scala - 猫作家矢量是空的,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41780471/

相关文章:

monads - 为什么验证会违反 monad 法则?

scala - cats.effect.IO 可以排序吗,即它在 Traverse 类型类中吗?

scala - Doobie 无法找到或构造类型 T 的 Read 实例

Scala 编译器在使用泛型的方法中显示 "No TypeTag available for T"

scala - Spark : SAXParseException while writing to parquet on s3

events - Scala Swing 事件中使用的反引号

scala - 与猫的三个列表的笛卡尔积

scala - 使用相互递归函数时,是否有一种简单的方法来处理流?

scala - Scala-没有TypeTag可用当使用案例类尝试获取TypeTag时发生异常吗?

scala - 猫缺少 Intersperse?