【问题标题】:How to fold on list of WriterT in cats如何折叠猫的WriterT列表
【发布时间】:2020-09-22 21:01:28
【问题描述】:

我希望在不运行它们的情况下将 Writer Monad 列表从猫折叠到一位大作家。 例如:

import cats.data.Writer
import cats.instances.vector._
import cats.instances.list._
import cats.instances.tuple._
import cats.Foldable

val result = for {
  i <- Writer(Vector("hello"), Vector(1))
  j <- Writer(Vector("bye"), Vector(2))
} yield j

val result2 = for {
  x <- Writer(Vector("hi"), Vector(33))
  y <- Writer(Vector("ciao"), Vector(55))
} yield y

val l = List(result, result2)

val result3 = for {
  t <- result
  z <- result2
} yield z // Success !!!

val l = List(result, result2)

// Logically:
// val result3 = for {
//   r <- l
//   o <- r
// } yield o
// But will not compile without Monad Transformer


// With run
val l1: List[(Vector[String], Vector[Int])] = l.map(_.run)

val result5 = Foldable[List].combineAll(l1)

我相信这种组合必须有一个功能构造,而无需运行 Writers

【问题讨论】:

  • 您期望的输入和输出是什么?你在寻找类似List[WriterT[F,L,V]] =&gt; WriterT[F,L,V] 的东西吗?
  • 那么running 和WriterT 的预期输出会是(Vector("hello", "bye", "hi", "ciao"), Vector(55))吗?

标签: scala scala-cats writer-monad


【解决方案1】:

您可以使用Vector 直接跳到result5,这样您就拥有相同的容器类型,然后使用l.sequence.map(_.flatten) 查看 Traverse 类型类,因为俗话说“It always Traverse”。

import cats.data.{Writer, WriterT}
import cats.instances.vector._
import cats.instances.list._
import cats.instances.tuple._
import cats.{Foldable, Id}
import cats.implicits._

val result = for {
  i <- Writer(Vector("hello"), Vector(1))
  j <- Writer(Vector("bye"), Vector(2))
} yield j

val result2 = for {
  x <- Writer(Vector("hi"), Vector(33))
  y <- Writer(Vector("ciao"), Vector(55))
} yield y

val l = Vector(result, result2)

val result3 = for {
  t <- result
  z <- result2
} yield z // Success !!!

// val l = List(result, result2) -- this is a duplicate

val result5: WriterT[Id, Vector[String], Vector[Int]] = l.sequence.map(_.flatten)

result5 将具有以下值:

WriterT((Vector(hello, bye, hi, ciao),Vector(2, 55)))

【讨论】:

  • 导入 cats.implicits._ 给我带来了一些问题,但 import cats.syntax.traverse._ 就像魔术一样工作。
【解决方案2】:

感谢@NigelBeans 的回答。 我将在这里发布工作解决方案,因为我使用答案中的确切导入存在一些隐含冲突:

import cats.data.Writer
import cats.instances.vector._
import cats.instances.list._
import cats.instances.tuple._
import cats.Foldable
import cats.syntax.traverse._

val result1 = for {
  i <- Writer(Vector("hello"), Vector(1))
  j <- Writer(Vector("bye"), Vector(2))
} yield j

val result2 = for {
  x <- Writer(Vector("hi"), Vector(33))
  y <- Writer(Vector("ciao"), Vector(55))
} yield y

val l = Vector(result1, result2)

val result3 = l.flatSequence

println(result3.run) // (Vector(hello, bye, hi, ciao),Vector(2, 55))

【讨论】:

    猜你喜欢
    • 2015-12-01
    • 2020-04-20
    • 2019-10-28
    • 2016-09-02
    • 2018-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多