如何在猫的 WriterT 列表中折叠
How to fold on list of WriterT in cats
我希望将 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)
我相信在没有 运行 作家
的情况下,这种组合必须有一个功能结构
您可以使用 Vector
直接跳到 result5
,这样您就拥有相同的容器类型,然后使用 l.sequence.map(_.flatten)
查看 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)))
感谢@NigelBeans 的回答。
我只是 post 这里的工作解决方案,因为我使用答案中的确切导入有一些隐含的冲突:
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))
我希望将 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)
我相信在没有 运行 作家
的情况下,这种组合必须有一个功能结构您可以使用 Vector
直接跳到 result5
,这样您就拥有相同的容器类型,然后使用 l.sequence.map(_.flatten)
查看 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)))
感谢@NigelBeans 的回答。 我只是 post 这里的工作解决方案,因为我使用答案中的确切导入有一些隐含的冲突:
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))