分配中的提取器和提取器

时间:2016-10-27 09:00:47

标签: scala

我对提取器有疑问。

如果我能这样做:

val a :: b = List(1, 2, 3)

为什么我不能这样做:

val c = for ( a :: b <- List(1, 2, 3) } yield a

2 个答案:

答案 0 :(得分:2)

Scala中for-yield表达式的翻译(不使用警卫)是map函数。如果您尝试使用map代替,那么对代码的怪癖似乎有点明确:

List(1, 2, 3).map((x: Int) => ???)

当您map超过List[+A]时,您可以一次投影一个值。您不需要在高阶函数内的一次性使用整个列表。

相反,当在列表本身上使用模式匹配时,编译器会将您的第一个示例转换为(在一些清理之后):

def main(args: Array[String]): Unit = {
  private[this] val x$1: (Int, List[Int]) = List(1, 2, 3) match {
    case (head: Int, tl: List[Int])scala.collection.immutable.::[Int]((a @ _), (b @ _)) => Tuple2[Int, List[Int]](a, b)
  };

  val a: Int = x$1._1;
  val b: List[Int] = x$1._2;
  ()

List[Int]上的模式匹配,与头尾相匹配。对于常规模式匹配,它只是简单的合成糖,与for-yield相同,是map的合成糖。他们只是做不同的事情

答案 1 :(得分:0)

在Yuval回答之后,我已经理解为什么它不起作用。

如果对第一个值感兴趣,则使用等效语法:

val first = for (a <- List(1, 2, 3).headOption) yield a