@@ -35,48 +35,59 @@ import scala.annotation.nowarn
3535 * which is expected to be more efficient than calling both `isDefinedAt`
3636 * and `apply`.
3737 *
38- * The main distinction between `PartialFunction` and [[scala.Function1 ]] is
39- * that the user of a `PartialFunction` may choose to do something different
40- * with input that is declared to be outside its domain. For example:
38+ * Note that `isDefinedAt` may itself throw an exception while evaluating pattern guards
39+ * or other parts of the `PartialFunction`. The same caveat holds for `applyOrElse`.
4140 *
4241 * {{{
4342 * val sample = 1 to 10
4443 * def isEven(n: Int) = n % 2 == 0
44+ *
4545 * val eveningNews: PartialFunction[Int, String] = {
4646 * case x if isEven(x) => s"\$x is even"
4747 * }
4848 *
49- * // The method collect is described as "filter + map"
49+ * // The method " collect" is described as "filter + map"
5050 * // because it uses a PartialFunction to select elements
5151 * // to which the function is applied.
5252 * val evenNumbers = sample.collect(eveningNews)
5353 *
54+ * // It's more usual to write the PartialFunction as a block of case clauses
55+ * // called an "anonymous pattern-matching function". Since the collect method
56+ * // expects a PartialFunction, one is synthesized from the case clauses.
57+ * def evenly = sample.collect { case x if isEven(x) => s"\$x is even" }
58+ *
59+ * // A method that takes a Function will get one, using the same syntax.
60+ * // Note that all cases are supplied since Function has no `isDefinedAt`.
61+ * def evened = sample.map { case odd if !isEven(odd) => odd + 1 case even => even }
62+ * }}}
63+ *
64+ * The main distinction between `PartialFunction` and [[scala.Function1 ]] is
65+ * that the client of a `PartialFunction` can perform an alternative computation
66+ * with input that is reported to be outside the domain of the function.
67+ *
68+ * For example:
69+ *
70+ * {{{
5471 * val oddlyEnough: PartialFunction[Int, String] = {
5572 * case x if !isEven(x) => s"\$x is odd"
5673 * }
5774 *
5875 * // The method orElse allows chaining another PartialFunction
5976 * // to handle input outside the declared domain.
60- * val numbers = sample.map(eveningNews orElse oddlyEnough)
77+ * val numbers = sample.map(eveningNews. orElse( oddlyEnough) )
6178 *
62- * // same as
79+ * // The same computation but with a function literal that calls applyOrElse
80+ * // with oddlyEnough as fallback, which it can do because a PartialFunction is a Function.
6381 * val numbers = sample.map(n => eveningNews.applyOrElse(n, oddlyEnough))
82+ * }}}
6483 *
65- * val half: PartialFunction[Int, Int] = {
66- * case x if isEven(x) => x / 2
67- * }
68- *
69- * // Calculating the domain of a composition can be expensive.
70- * val oddByHalf = half.andThen(oddlyEnough)
71- *
72- * // Invokes `half.apply` on even elements!
73- * val oddBalls = sample.filter(oddByHalf.isDefinedAt)
74- *
75- * // Better than filter(oddByHalf.isDefinedAt).map(oddByHalf)
76- * val oddBalls = sample.collect(oddByHalf)
84+ * As a convenience, function literals can also be adapted into partial functions
85+ * when needed. If the body of the function is a match expression, then the cases
86+ * are used to synthesize the PartialFunction as already shown.
7787 *
78- * // Providing "default" values.
79- * val oddsAndEnds = sample.map(n => oddByHalf.applyOrElse(n, (i: Int) => s"[\$i]"))
88+ * {{{
89+ * // The partial function isDefinedAt inputs resulting in the Success case.
90+ * val inputs = List("1", "two", "3").collect(x => Try(x.toInt) match { case Success(i) => i })
8091 * }}}
8192 *
8293 * @note Optional [[Function ]]s, [[PartialFunction ]]s and extractor objects
@@ -86,7 +97,7 @@ import scala.annotation.nowarn
8697 * | :---: | --- | --- | --- |
8798 * | from a [[PartialFunction ]] | [[Predef.identity ]] | [[lift ]] | [[Predef.identity ]] |
8899 * | from optional [[Function ]] | [[Function1.UnliftOps#unlift ]] or [[Function.unlift ]] | [[Predef.identity ]] | [[Function1.UnliftOps#unlift ]] |
89- * | from an extractor | `{ case extractor(x) => x }` | `extractor.unapply _ ` | [[Predef.identity ]] |
100+ * | from an extractor | `{ case extractor(x) => x }` | `extractor.unapply(_) ` | [[Predef.identity ]] |
90101 *
91102 *
92103 * @define applyOrElseOrElse Note that calling [[isDefinedAt ]] on the resulting partial function
0 commit comments