作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有一个像这样的字符串到 IO 的映射 Map[String, IO[String]]
,我想把它变成IO[Map[String, String]]
.怎么做?
最佳答案
你必须小心一点。 Scala 中的映射是无序的,因此如果您尝试使用猫的 sequence
像这样…
import cats.instances.map._
import cats.effect.IO
import cats.UnorderedTraverse
object Example1 {
type StringMap[V] = Map[String, V]
val m: StringMap[IO[String]] = Map("1" -> IO{println("1"); "1"})
val n: IO[StringMap[String]] = UnorderedTraverse[StringMap].unorderedSequence[IO, String](m)
}
Error: could not find implicit value for evidence parameter of type cats.CommutativeApplicative[cats.effect.IO]
map2(u, v)(f) = map2(v, u)(flip(f)) // Commutativity (Scala)
CommutativeApplicative[IO]
的实例来编译上述代码。但这仍然不能使 IO monad 可交换。如果您运行以下代码,您可以看到副作用的处理顺序不同:
import cats.effect.IO
import cats.CommutativeApplicative
object Example2 {
implicit object FakeEvidence extends CommutativeApplicative[IO] {
override def pure[A](x: A): IO[A] = IO(x)
override def ap[A, B](ff: IO[A => B])(fa: IO[A]): IO[B] =
implicitly[Applicative[IO]].ap(ff)(fa)
}
def main(args: Array[String]): Unit = {
def flip[A, B, C](f: (A, B) => C) = (b: B, a: A) => f(a, b)
val fa = IO{println(1); 1}
val fb = IO{println(true); true}
val f = (a: Int, b: Boolean) => s"$a$b"
println(s"IO is not commutative: ${FakeEvidence.map2(fa, fb)(f).unsafeRunSync()} == ${FakeEvidence.map2(fb, fa)(flip(f)).unsafeRunSync()} (look at the side effects above^^)")
}
}
1
true
true
1
IO is not commutative: 1true == 1true (look at the side effects above^^)
import cats.effect.IO
import cats.implicits._
object Example3 {
val m: Map[String, IO[String]] = Map("1" -> IO {println("1"); "1"})
val l: IO[List[(String, String)]] = m.toList.traverse[IO, (String, String)] { case (s, io) => io.map(s2 => (s, s2))}
val n: IO[Map[String, String]] = l.map { _.toMap }
}
关于scala - 猫效应:如何将 Map[x,IO[y]] 转换为 IO[Map[x,y]],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53945996/
我是一名优秀的程序员,十分优秀!