scala中的问题理解脱糖?

Problem in scala for-comprehension de-sugar?

我有以下理解,我使用命令 scala -Xprint:parser ForComprehensionDemo.scala 去除了糖分。当我复制脱糖方法并调用它时,它产生的结果与 for-comprehension 不同。知道为什么吗?

求理解:

    object ForComprehensionDemo {
      def main(args: Array[String]): Unit = {
        forWithIf(true)
      }

      def forWithIf(condition: Boolean) = {
        val x = for {
          a <- name(0)
          b <- if (condition) {
            name(1)
            name(2)
          } else {
            name(100)
          }
          c <- name(2)
        } yield {
          a + b + c
        }

        println(x)
      }

   def name(x: Int): Option[String] = {
     println("called for :" + x)
     x match {
       case 0 => Some(" aa ")
       case 1 => Some(" bb ")
       case 2 => Some(" cc ")
       case _ => Some(" not identified ")
     }
    }   
   }

产生结果:

called for :0
called for :1
called for :2
called for :2
Some( aa  cc  cc )

脱糖码

    def forWithIf(condition: Boolean) = {
      val x = name(0).flatMap(((a) => if (condition)
  {
    name(1);
    name(2)
  }
else
  name(100).flatMap(((b) => name(2).map(((c) => a.$plus(b).$plus(c)))))));
      println(x)
    };

产生结果:

called for :0
called for :1
called for :2
Some( cc )

只是漂亮打印机中的一个错误。它缺少 if-else 周围的括号。

总的来说,scala 2 不能非常忠实地代表 parens,但 scala 3 更好。

package desugar {
  object ForComprehensionDemo extends scala.AnyRef {
    def main(args: Array[String]): Unit = forWithIf(true);
    def forWithIf(condition: Boolean) = {
      val x = name(0).flatMap(((a) => (if (condition)
  {
    name(1);
    name(2)
  }
else
  name(100)).flatMap(((b) => name(2).map(((c) => a.$plus(b).$plus(c)))))));
      println(x)
    };
    def name(x: Int): Option[String] = {
      println("called for :".$plus(x));
      x match {
        case 0 => Some(" aa ")
        case 1 => Some(" bb ")
        case 2 => Some(" cc ")
        case _ => Some(" not identified ")
      }
    }
  }
}

我很好奇 Scala 3 说了什么。 -Xprint:all 在打字员之后说:

          sugar.ForComprehensionDemo.name(0).flatMap[String](
            {
              def $anonfun(a: String): Option[String] = 
                (if condition then 
                  {
                    sugar.ForComprehensionDemo.name(1)
                    sugar.ForComprehensionDemo.name(2)
                  }
                 else 
                  {
                    sugar.ForComprehensionDemo.name(100)
                  }
                ).flatMap[String](
                  {
                    def $anonfun(b: String): Option[String] = 
                      sugar.ForComprehensionDemo.name(2).map[String](
                        {
                          def $anonfun(c: String): String = 
                            {
                              a.+(b).+(c)
                            }
                          closure($anonfun)
                        }
                      )
                    closure($anonfun)
                  }
                )
              closure($anonfun)
            }
          )

闭包更难理解,但它有括号。在解析器之后打印没有用。

只是为了比较这里是 IntelliJ Desugar Scala code... 输出(手动缩写 FQN)

def forWithIf(condition: Boolean) = {
  val x = name(0)
    .flatMap(((a) =>
      (if (condition) {
        name(1);
        name(2)
      } else {
        name(100)
      })
        .flatMap(((b) =>
          name(2)
            .map(((c) => a.$plus(b).$plus(c)))))
      ));
  println(x)
};

确认 som-snytt 的回答。