Scala 为什么这段代码依赖于'withFilter',或者这是一个bug?

Scala 为什么这段代码依赖于'withFilter',或者这是一个bug?,scala,scala-cats,Scala,Scala Cats,我正在一个项目中与cats合作,不明白为什么在这段代码中会出现这种奇怪的编译器错误: 使用:Int它不会编译 供参考 依赖关系 sbt关于 sbt控制台 问题: 有人知道为什么只有在使用相应类型显式注释时,此代码才依赖于带过滤器的,或者这是一个错误吗?为了理解,将flatMap、map和带过滤器的组合编译为withFilter用于理解的if子句,但即使没有if,仍会生成withFilter——请参见两种情况下,已删除的代码看起来不同 sbt控制台带有-Xprint:typer 在将scalacO

我正在一个项目中与cats合作,不明白为什么在这段代码中会出现这种奇怪的编译器错误:

使用
:Int
它不会编译 供参考 依赖关系
sbt关于
sbt控制台
问题:
有人知道为什么只有在使用相应类型显式注释时,此代码才依赖于带过滤器的
,或者这是一个错误吗?

为了理解,将
flatMap
map
带过滤器的组合编译为
withFilter
用于理解的
if
子句,但即使没有
if
,仍会生成
withFilter
——请参见两种情况下,已删除的代码看起来不同

sbt控制台
带有
-Xprint:typer
在将
scalacOptions++=Seq(“-Xprint:typer”)
添加到
build.sbt
中后,可以在
sbt控制台上打印已删除的代码:

不带
:Int
但是,我仍然不知道为什么显式案例会使用filter添加这个
。编译器内部的策略似乎是信任程序员给出的显式类型注释

似乎是有意的 一位同事与我分享的信息表明,通常情况下,发电机LHS上的所有内容都是按模式处理的


生成器p这解释了为什么此代码“一般”依赖于
with filter
,感谢这些链接帮助我现在理解了为什么会发生这种情况。但我仍然感到困惑,为什么代码的注释版本会引发问题,而非注释版本不会?
README.md
在一个没有注释的示例中解释了这个问题。就我目前的理解而言,问题应该是有没有类型注释。我将澄清一下我的问题。生成的代码似乎试图从集合中删除非Int成员
scala> :paste
:paste
// Entering paste mode (ctrl-D to finish)

object Test {
  def exec[F[_]: cats.Monad] = for {i: Int <- cats.data.EitherT.fromEither[F](Right(0))} yield i
}

^D
// Exiting paste mode, now interpreting.

<pastie>:12: error: value withFilter is not a member of cats.data.EitherT[F,E,Int]
  def exec[F[_]: cats.Monad] = for {i: Int <- cats.data.EitherT.fromEither[F](Right(0))} yield i
scala> :paste
:paste
// Entering paste mode (ctrl-D to finish)

object Test {
  def exec[F[_]: cats.Monad] = for {i <- cats.data.EitherT.fromEither[F](Right(0))} yield i
}

^D
// Exiting paste mode, now interpreting.

warning: there was one feature warning; for details, enable `:setting -feature' or `:replay -feature'
defined object Test
"org.typelevel" %% "cats-core" % "1.1.0"
"org.typelevel" %% "cats-macros" % "1.1.0"
"org.typelevel" %% "cats-kernel" % "1.1.0"
sbt:cats-eithert-problem> about
[info] This is sbt 1.1.4
[info] The current project is ProjectRef(uri("file:/Users/isaias/Projects/cats-eithert-problem/"), "root") 0.1.0-SNAPSHOT
[info] The current project is built against Scala 2.12.5
[info] Available Plugins: sbt.plugins.IvyPlugin, sbt.plugins.JvmPlugin, sbt.plugins.CorePlugin, sbt.plugins.JUnitXmlReportPlugin, sbt.plugins.Giter8TemplatePlugin, com.timushev.sbt.updates.UpdatesPlugin, spray.revolver.RevolverPlugin, com.typesafe.sbt.SbtNativePackager, com.typesafe.sbt.packager.archetypes.JavaAppPackaging, com.typesafe.sbt.packager.archetypes.JavaServerAppPackaging, com.typesafe.sbt.packager.archetypes.jar.ClasspathJarPlugin, com.typesafe.sbt.packager.archetypes.jar.LauncherJarPlugin, com.typesafe.sbt.packager.archetypes.scripts.AshScriptPlugin, com.typesafe.sbt.packager.archetypes.scripts.BashStartScriptPlugin, com.typesafe.sbt.packager.archetypes.scripts.BatStartScriptPlugin, com.typesafe.sbt.packager.archetypes.systemloader.SystemVPlugin, com.typesafe.sbt.packager.archetypes.systemloader.SystemdPlugin, com.typesafe.sbt.packager.archetypes.systemloader.SystemloaderPlugin, com.typesafe.sbt.packager.archetypes.systemloader.UpstartPlugin, com.typesafe.sbt.packager.debian.DebianDeployPlugin, com.typesafe.sbt.packager.debian.DebianPlugin, com.typesafe.sbt.packager.debian.JDebPackaging, com.typesafe.sbt.packager.docker.DockerPlugin, com.typesafe.sbt.packager.docker.DockerSpotifyClientPlugin, com.typesafe.sbt.packager.jdkpackager.JDKPackagerDeployPlugin, com.typesafe.sbt.packager.jdkpackager.JDKPackagerPlugin, com.typesafe.sbt.packager.linux.LinuxPlugin, com.typesafe.sbt.packager.rpm.RpmDeployPlugin, com.typesafe.sbt.packager.rpm.RpmPlugin, com.typesafe.sbt.packager.universal.UniversalDeployPlugin, com.typesafe.sbt.packager.universal.UniversalPlugin, com.typesafe.sbt.packager.windows.WindowsDeployPlugin, com.typesafe.sbt.packager.windows.WindowsPlugin
[info] sbt, sbt plugins, and build definitions are using Scala 2.12.4
sbt:cats-eithert-problem> console
[info] Starting scala interpreter...
Welcome to Scala 2.12.5 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_144).
Type in expressions for evaluation. Or try :help.
def exec         [F[_] >: [_]Nothing <: [_]Any](implicit evidence$1: cats.Monad[F]): cats.data.EitherT[F,Nothing,Int] = cats.data.EitherT.fromEither[F]
  .apply[Nothing, Int](scala.`package`.Right.apply[Nothing, Int](0))(evidence$1)
  .map[Int](((i: Int) => i))(evidence$1)
def <exec: error>[F[_] >: [_]Nothing <: [_]Any](implicit evidence$1: cats.Monad[F]): <error>                          = cats.data.EitherT.fromEither[F]
  (Right(0)).<withFilter: error>((
    (<check$ifrefutable$1: error>: <error>) => 
      <check$ifrefutable$1: error>: @scala.unchecked match {
        case (<i: error> @ (_: Int)) => true
        case _ => false
      }
    )
  )
  .<map: error>(((i: Int) => i))
scala -Xprint:typer -e "for { i <- Option(0) } yield i"
[[syntax trees at end of                     typer]] // scalacmd2652417036573431085.scala
package <empty> {
  object Main extends scala.AnyRef {
    def <init>(): Main.type = {
      Main.super.<init>();
      ()
    };
    def main(args: Array[String]): Unit = {
      final class $anon extends scala.AnyRef {
        def <init>(): <$anon: AnyRef> = {
          $anon.super.<init>();
          ()
        };
        scala.Option.apply[Int](0).map[Int](((i: Int) => i))
      };
      {
        new $anon();
        ()
      }
    }
  }
}
scala -Xprint:typer -e "for { i: Int <- Option(0) } yield i"
[[syntax trees at end of                     typer]] // scalacmd7960547396256503452.scala
package <empty> {
  object Main extends scala.AnyRef {
    def <init>(): Main.type = {
      Main.super.<init>();
      ()
    };
    def main(args: Array[String]): Unit = {
      final class $anon extends scala.AnyRef {
        def <init>(): <$anon: AnyRef> = {
          $anon.super.<init>();
          ()
        };
        scala.Option.apply[Int](0).withFilter(((check$ifrefutable$1: Int) => (check$ifrefutable$1: Int @unchecked) match {
  case (i @ (_: Int)) => true
  case _ => false
})).map[Int](((i: Int) => i))
      };
      {
        new $anon();
        ()
      }
    }
  }
}