1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
|
/* __ *\
** ________ ___ / / ___ Scala API **
** / __/ __// _ | / / / _ | (c) 2011, LAMP/EPFL **
** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
** /____/\___/_/ |_/____/_/ | | **
** |/ **
\* */
package scala.runtime
/** `AbstractPartialFunction` reformulates all operations of its supertrait `PartialFunction` in terms of `isDefinedAt` and `applyOrElse`.
*
* This allows more efficient implementations in many cases:
* - optimized `orElse` method supports chained `orElse` in linear time,
* and with no slow-down if the `orElse` part is not needed.
* - optimized `lift` method helps to avoid double evaluation of pattern matchers & guards
* of partial function literals.
*
* This trait is used as a basis for implementation of all partial function literals
* with non-exhaustive matchers.
*
* Use of `AbstractPartialFunction` instead of `PartialFunction` as a base trait for
* user-defined partial functions may result in better performance
* and more predictable behavior w.r.t. side effects.
*
* @author Pavel Pavlov
* @since 2.10
*/
abstract class AbstractPartialFunction[@specialized(scala.Int, scala.Long, scala.Float, scala.Double, scala.AnyRef) -T1, @specialized(scala.Unit, scala.Boolean, scala.Int, scala.Float, scala.Long, scala.Double, scala.AnyRef) +R] extends Function1[T1, R] with PartialFunction[T1, R] { self =>
// this method must be overridden for better performance,
// for backwards compatibility, fall back to the one inherited from PartialFunction
// this assumes the old-school partial functions override the apply method, though
// override def applyOrElse[A1 <: T1, B1 >: R](x: A1, default: A1 => B1): B1 = ???
// probably okay to make final since classes compiled before have overridden against the old version of AbstractPartialFunction
// let's not make it final so as not to confuse anyone
/*final*/ def apply(x: T1): R = applyOrElse(x, PartialFunction.empty)
override final def andThen[C](k: R => C) : PartialFunction[T1, C] =
new AbstractPartialFunction[T1, C] {
def isDefinedAt(x: T1): Boolean = self.isDefinedAt(x)
override def applyOrElse[A1 <: T1, C1 >: C](x: A1, default: A1 => C1): C1 =
self.applyOrElse(x, PartialFunction.fallbackToken) match {
case PartialFunction.FallbackToken => default(x)
case z => k(z)
}
}
// TODO: remove
protected def missingCase(x: T1): R = throw new MatchError(x)
}
/** `AbstractTotalFunction` is a partial function whose `isDefinedAt` method always returns `true`.
*
* This class is used as base class for partial function literals with
* certainly exhaustive pattern matchers.
*
* @author Pavel Pavlov
* @since 2.10
*/
abstract class AbstractTotalFunction[@specialized(scala.Int, scala.Long, scala.Float, scala.Double, scala.AnyRef) -T1, @specialized(scala.Unit, scala.Boolean, scala.Int, scala.Float, scala.Long, scala.Double, scala.AnyRef) +R] extends Function1[T1, R] with PartialFunction[T1, R] {
final def isDefinedAt(x: T1): Boolean = true
override final def applyOrElse[A1 <: T1, B1 >: R](x: A1, default: A1 => B1): B1 = apply(x)
override final def orElse[A1 <: T1, B1 >: R](that: PartialFunction[A1, B1]): PartialFunction[A1, B1] = this
//TODO: check generated code for PF literal here
override final def andThen[C](k: R => C): PartialFunction[T1, C] = { case x => k(apply(x)) }
}
|