加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

Scalaz:过滤器在| @ |中起什么作用?

发布时间:2020-12-16 09:56:55 所属栏目:安全 来源:网络整理
导读:我们在Futures上使用了WriterT monad转换器希望从异步应用程序中获取更多有组织的日志,但是我们遇到了一些麻烦. 如果我编译下面的应用程序,我会收到以下错误.请注意,这不是关于withFilter的警告. [error] value filter is not a member of scalaz.WriterT[sc
我们在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,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来查看desugaring期间发生的事情通常很方便(这是我唯一一次建议从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-comprehension中的类型案例模式匹配.即使编译器将验证匹配是否安全(例如,对于{x:String< - Option(1)},yield x将无法编译),它仍然可以用于过滤操作.我不确定为什么 - 这可能是有原因的,而且这是一个很好的理由. 您收到有关过滤器的消息,因为在这种情况下,这是编译器的最后手段.首先,它会尝试去调用withFilter,如果找不到withFilter,它将使用过滤器(至少在集合库的实现中,这样的情况通常效率较低).在WriterT的情况下,它既没有找到(因为过滤作者在一般情况下没有意义),所以它抱怨它尝试的最后一个. 解决方案就是不使用类型大小写匹配.为{z< - ...} yield z写一个简单的旧的东西,一切都会正常工作.事实上,I’d suggest not ever using type-case matching-这是运行时反射相关问题最终出现在代码中的最偷偷摸摸的方式.在这种情况下,将在编译时检查操作(至少在明显的情况下),但它仍然是不必要的,可能效率较低.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读