gpt4 book ai didi

scala - 为什么定义了这个 PartialFunction 但在 Scala 中应用后仍然(正确)崩溃?

转载 作者:行者123 更新时间:2023-12-04 02:39:41 25 4
gpt4 key购买 nike

我想尝试使用深度模式匹配用例的部分函数。这最初(当然)在应用 Some(Some(3)) 后不起作用,但似乎已定义:

def deepTest : PartialFunction [Option[Option[Int]], Int] = {
case Some(v) => v match {
case None => 3
}
case None => 1
}

我认为通过解耦嵌套模式匹配,事情会更容易:

def deepTestLvl1 : PartialFunction [Option[Option[Int]], Option[Int]] = {
case Some(v) => v
case None => Some(1)
}


def deepTestLvl2 : PartialFunction [Option[Int], Int] = {
case None => 3
}

但结果如下:

scala> (deepTestLvl1 andThen deepTestLvl2) isDefinedAt(Some(Some(3)))
res24: Boolean = true

申请后:

scala> (deepTestLvl1 andThen deepTestLvl2) (Some(Some(3)))
scala.MatchError: Some(3) (of class scala.Some)
at scala.PartialFunction$$anon$1.apply(PartialFunction.scala:248)
at scala.PartialFunction$$anon$1.apply(PartialFunction.scala:246)
at $anonfun$deepTestLvl2$1.applyOrElse(<console>:7)
at $anonfun$deepTestLvl2$1.applyOrElse(<console>:7)
....
at scala.tools.nsc.MainGenericRunner.runTarget$1(MainGenericRunner.scala:83)
at scala.tools.nsc.MainGenericRunner.process(MainGenericRunner.scala:96)
at scala.tools.nsc.MainGenericRunner$.main(MainGenericRunner.scala:105)
at scala.tools.nsc.MainGenericRunner.main(MainGenericRunner.scala)

我做错了什么吗?当我按顺序编写 deepTestLvl{1,2} 并给我正确答案时,不应该调用两次 isDefinedAt 吗?

最佳答案

很好的问题。

让我们检查源代码,看看幕后发生了什么:

override def andThen[C](k: B => C): PartialFunction[A, C] =
new AndThen[A, B, C] (this, k)

我们可以在这里观察到 andThen 甚至不期望部分函数,任何转换结果的函数都可以。您的代码有效,因为:trait PartialFunction[-A, +B] extends (A => B)。这实际上可以在 the documentation 中找到:

def andThen[C](k: (B) ⇒ C): PartialFunction[A, C]

Composes this partial function with a transformation function that gets applied to results of this partial function.

C the result type of the transformation function.

k the transformation function

returns a partial function with the same domain as this partial function, which maps arguments x to k(this(x)).

因此目前无法按照您希望的方式链接 PartialFunction,因为正如 Robin 所说,这需要应用该函数。除了计算量大它还可能有副作用,这是一个更大的问题。

更新

拼凑出您正在寻找的实现。 谨慎使用!正如我已经提到的,如果您的代码有副作用,它将导致问题:

implicit class PartialFunctionExtension[-A, B](pf: PartialFunction[A, B]) {
def andThenPf[C](pf2: PartialFunction[B, C]) = new PfAndThen(pf, pf2)

class PfAndThen[+C](pf: PartialFunction[A, B], nextPf: PartialFunction[B, C]) extends PartialFunction[A, C] {
def isDefinedAt(x: A) = pf.isDefinedAt(x) && nextPf.isDefinedAt(pf.apply(x))

def apply(x: A): C = nextPf(pf(x))
}
}

尝试一下:

deepTestLvl1.andThenPf(deepTestLvl2).isDefinedAt(Some(Some(3)))  // false
deepTestLvl1.andThenPf(deepTestLvl2).isDefinedAt(Some(None)) // true
deepTestLvl1.andThenPf(deepTestLvl2).apply(Some(None)) // 3

关于scala - 为什么定义了这个 PartialFunction 但在 Scala 中应用后仍然(正确)崩溃?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20166468/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com