为什么scala @tailrec无法在Option.flatMap上使用?

tri*_*oid 5 monads scala tail-recursion

在scala中,以下两个功能的作用完全相同:

@tailrec
final def fn(str: String): Option[String] = {
  Option(str).filter(_.nonEmpty).flatMap { v =>
    fn(v.drop(1))
  }
}

@tailrec
final def fn2(str: String): Option[String] = {
  Option(str).filter(_.nonEmpty) match {
    case None    => None
    case Some(v) => fn2(v.drop(1))
  }
}
Run Code Online (Sandbox Code Playgroud)

但是@tailrec仅在第二种情况下有效,在第一种情况下,它将生成以下错误:

错误:无法优化@tailrec带注释的方法fn:它包含不在尾部位置的递归调用Option(str).filter(_。nonEmpty).flatMap {v =>

为什么会出现此错误?以及为什么这两个代码生成不同种类的JVM字节码

jwv*_*wvh 1

考虑以下:

List('a', 'b').flatMap(List(_,'g'))  //res0: List[Char] = List(a, g, b, g)
Run Code Online (Sandbox Code Playgroud)

我似乎很明显flatMap()正在进行一些内部后处理以实现该结果。还有什么办法可以List('a','g')与 结合起来List('b','g')