为什么使用变量可以使偏函数变得不那么偏?

Sum*_*uma 4 scala partialfunction partial-functions

我不明白为什么使用变量作为临时值会使部分函数不同:

val f1: PartialFunction[Option[Int], Int] = { b =>
  val i = identity(b)
  i match {
    case Some(res) => res
  }
}
val f2: PartialFunction[Option[Int], Int] = { b =>
  identity(b) match {
    case Some(res) => res
  }
}

f1.isDefinedAt(None)
f2.isDefinedAt(None)
Run Code Online (Sandbox Code Playgroud)

Scala 2.13.12 和 Scala 3.3.1 的结果是true/ 。false第一个版本显示匹配详尽性警告,第二个版本则没有。该代码无法使用 Scala 2.12.18 编译,错误出现在第一个版本中:

类型不匹配;

找到:选项[Int] => Int

必需:PartialFunction[Option[Int],Int]

第二个版本怎么比第一个版本更“偏颇”呢?

Sum*_*uma 6

我认为语言规范回答了这个问题:

https://www.scala-lang.org/files/archive/spec/3.4/06-expressions.html

PartialFunction当需要a 时,isDefinedAt会合成一个附加成员,该成员仅返回 true。但是,如果函数字面量的形状为x => x match { $...$ },则按isDefinedAt以下方式从模式匹配派生:匹配表达式中的每个情况的计算结果为true,如果没有默认情况,则添加一个计算结果为 的默认情况false

第一个版本不具有将单一抽象方法转换为部分函数的特殊情况的预期形状,因此创建了一个普通(总)函数,稍后将其转换为部分函数。

也许要求将部分函数编写为模式匹配匿名函数不会那么令人困惑,但我想这背后有一些原因或历史。