作者热门文章
- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我们在 Futures 上使用了 WriterT monad 转换器,希望从异步应用程序中获得更有条理的日志,但我们遇到了一些麻烦。
如果我编译下面的应用程序,我会收到以下错误。请注意,这不是关于 withFilter 的警告。
[error] value filter is not a member of scalaz.WriterT[scala.concurrent.Future,List[String],String]
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) }
}
最佳答案
使用反射库的 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/
我有一个构成Mouse角色的Moose类。 package My::Moose::Class; use Moose; has 'mouse_obj' => ( is => 'ro',
我正在玩字符串的位置界面。我知道 How can I slice a string like Python does in Perl 6? ,但我很好奇我是否可以让这件事只为傻笑而工作。 我想出了这个
我是一名优秀的程序员,十分优秀!