gpt4 book ai didi

Scalaz:过滤器在|@|中扮演什么角色?

转载 作者:行者123 更新时间:2023-12-04 18:04:16 24 4
gpt4 key购买 nike

我们在 Futures 上使用了 WriterT monad 转换器,希望从异步应用程序中获得更有条理的日志,但我们遇到了一些麻烦。

如果我编译下面的应用程序,我会收到以下错误。请注意,这不是关于 withFilter 的警告。

[error] value filter is not a member of scalaz.WriterT[scala.concurrent.Future,List[String],String]



为什么|@|这里需要过滤吗? Scalaz 是否为这种情况提供了隐式转换?
import scala.concurrent.ExecutionContext.Implicits.global
import scala.concurrent.Future
import scalaz._
import Scalaz._

object Failure extends App {

type LoggedT[F[_], A] = WriterT[F, List[String], A]
type LoggedFuture[A] = LoggedT[Future, A]

//this is the applicative behavior that we want WriterT to preserve
val example = for {
z <- (Future("left") |@| Future("right")) { (x: String, y: String) => x + " " + y }
} yield z

example.onSuccess { case x => println(x) }

val test = for {
z: String <- (Future("left").liftM[LoggedT] |@| Future("right").liftM[LoggedT]) { (x: String, y: String) => x + " " + y }
} yield z

test.value.onSuccess { case x => println(x) }

}

错误发生在 Scala 版本:2.11.7 和 Scalaz 版本:7.2.0

最佳答案

使用反射库的 reify 通常很方便看看在脱糖过程中发生了什么(这是我唯一一次建议从 scala.reflect.runtime 导入任何东西,即使在这种情况下也只是在开发期间的 REPL 中):

scala> import scala.reflect.runtime.universe.reify
import scala.reflect.runtime.universe.reify

scala> reify(for { x: Int <- Option(1) } yield x)
res5: reflect.runtime.universe.Expr[Option[Int]] =
Expr[scala.Option[Int]](Option.apply(1).withFilter(((check$ifrefutable$1) => check$ifrefutable$1: @unchecked match {
case (x @ (_: Int)) => true
case _ => false
})).map(((x: Int) => x)))

问题在于理解中的类型案例模式匹配。即使编译器会验证匹配是否安全(例如 for { x: String <- Option(1) } yield x 不会编译),它仍然会被过滤操作。我不知道为什么——这可能是有原因的,甚至有很小的机会是一个很好的理由。

您收到一条关于 filter 的消息因为这是编译器在这种情况下的最后手段。首先,它会尝试对调用 withFilter 进行脱糖处理。 ,如果没有找到 withFilter ,它将使用 filter (在这种情况下,至少在集合库的实现中通常效率较低)。在 WriterT 的情况下它没有发现(因为在一般情况下过滤作家没有意义),所以它提示它尝试的最后一个。

解决方案就是不使用类型匹配。写一个普通的旧 for { z <- ... } yield z一切都会正常工作。事实上 I'd suggest not ever using type-case matching ——这是运行时反射相关问题最终出现在您的代码中的最隐秘方式。在这种情况下,将在编译时检查操作(至少在明显的情况下),但它仍然是不必要的并且可能效率较低。

关于Scalaz:过滤器在|@|中扮演什么角色?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34549180/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com