The arrival of scala.Zero. This adds nothing to the

existing codebase.  What is it good for then? It's good
for nothing.  Thank you, I'll be here all night.

git-svn-id: http://lampsvn.epfl.ch/svn-repos/scala/scala/trunk@19291 5e8d7ff9-d8ef-0310-90f0-a4852d11357a
This commit is contained in:
extempore 2009-10-26 20:56:14 +00:00
parent c421c018aa
commit 5f9f906158
2 changed files with 81 additions and 0 deletions

View File

@ -80,6 +80,12 @@ sealed abstract class Option[+A] extends Product {
*/
def getOrElse[B >: A](default: => B): B =
if (isEmpty) default else this.get
/** If the option is nonempty return its value,
* otherwise return the Zero for this type.
*/
def orZero[B >: A](implicit z: Zero[B]): B =
this getOrElse z.zero
/** If the option is nonempty, return a function applied to its value,
* wrapped in a Some i.e. <code>Some(f(this.get))</code>.

View File

@ -0,0 +1,75 @@
/* __ *\
** ________ ___ / / ___ Scala API **
** / __/ __// _ | / / / _ | (c) 2003-2009, LAMP/EPFL **
** __\ \/ /__/ __ |/ /__/ __ | **
** /____/\___/_/ |_/____/_/ | | **
** |/ **
\* */
package scala
import reflect.ClassManifest
import collection._
import xml.NodeSeq
/** A trait representing Zero of a given type. It should be understood
* that "Zero" can be context-dependant, for instance with respect to
* multiplication, Zero[Int] is 1. At present this class does not attempt
* to address more interesting uses, and provides the standard value of
* 0 for all the AnyVal types, and empty containers for many container types.
*
* @author Paul Phillips (standing on the shoulders of giants)
* @since 2.8
*/
trait Zero[+Z] {
val zero: Z
}
trait LowPriorityZeroImplicits {
import Zero.zero
// If we just provide a Zero for collection.Set, then immutable.Set and
// mutable.Set have no Zero, but if we try to provide both of those, then
// Zero[collection.Set] fails as ambiguous. Fortunately the prioritization
// mechanism let us deal with this with a subclass, but this isn't a
// terribly general solution...
implicit def MutableSeqZero[A] = zero[mutable.Seq[A]](mutable.Seq.empty)
implicit def MutableSetZero[A] = zero[mutable.Set[A]](mutable.Set.empty)
implicit def MutableMapZero[A, B] = zero[mutable.Map[A, B]](mutable.Map.empty)
}
object Zero extends LowPriorityZeroImplicits {
def apply[Z](implicit z: Zero[Z]) = z.zero
def zero[Z](z: Z): Zero[Z] = new Zero[Z] { val zero = z }
implicit object UnitZero extends Zero[Unit] { val zero = () }
implicit object StringZero extends Zero[String] { val zero = "" }
implicit object BooleanZero extends Zero[Boolean] { val zero = false }
implicit object ByteZero extends Zero[Byte] { val zero = (0: Byte) }
implicit object ShortZero extends Zero[Short] { val zero = (0: Short) }
implicit object IntZero extends Zero[Int] { val zero = 0 }
implicit object LongZero extends Zero[Long] { val zero = 0l }
implicit object CharZero extends Zero[Char] { val zero = (0: Char) }
implicit object FloatZero extends Zero[Float] { val zero = 0f }
implicit object DoubleZero extends Zero[Double] { val zero = 0d }
implicit object BigIntZero extends Zero[BigInt] { val zero = BigInt(0) }
implicit object BigDecimalZero extends Zero[BigDecimal] { val zero = BigDecimal(0) }
implicit object NodeSeqZero extends Zero[NodeSeq] { val zero = NodeSeq.Empty }
implicit def OptionZero[A] = zero[Option[A]](None)
implicit def ArrayZero[A: ClassManifest] = zero(Array.empty[A])
implicit def TraversableZero[A] = zero[Traversable[A]](Traversable.empty)
implicit def IterableZero[A] = zero[Iterable[A]](Iterable.empty)
implicit def ImmutableSeqZero[A] = zero[immutable.Seq[A]](immutable.Seq.empty)
implicit def ImmutableSetZero[A] = zero[immutable.Set[A]](immutable.Set.empty)
implicit def ImmutableMapZero[A, B] = zero[immutable.Map[A, B]](immutable.Map.empty)
implicit def IteratorZero[A] = zero[Iterator[A]](Iterator.empty)
implicit def IndexedSeqZero[A] = zero[IndexedSeq[A]](IndexedSeq.empty)
implicit def ListZero[A] = zero[List[A]](Nil)
implicit def StreamZero[A] = zero[Stream[A]](Stream.empty)
}