diff options
author | Paul Phillips <paulp@improving.org> | 2009-10-26 20:56:14 +0000 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2009-10-26 20:56:14 +0000 |
commit | 35a8ab3cddd27550ea8f3329483b065a2d83fae8 (patch) | |
tree | d69e27708e5371fec356ce99835e794e65afa7d5 | |
parent | 0b16c1266296e93339f56054f1b5e3f5908d3e55 (diff) | |
download | scala-35a8ab3cddd27550ea8f3329483b065a2d83fae8.tar.gz scala-35a8ab3cddd27550ea8f3329483b065a2d83fae8.tar.bz2 scala-35a8ab3cddd27550ea8f3329483b065a2d83fae8.zip |
The arrival of scala.Zero.
existing codebase. What is it good for then? It's good for nothing.
Thank you, I'll be here all night.
-rw-r--r-- | src/library/scala/Option.scala | 6 | ||||
-rw-r--r-- | src/library/scala/Zero.scala | 75 |
2 files changed, 81 insertions, 0 deletions
diff --git a/src/library/scala/Option.scala b/src/library/scala/Option.scala index c3605c7c1b..aa05a46a02 100644 --- a/src/library/scala/Option.scala +++ b/src/library/scala/Option.scala @@ -81,6 +81,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>. * Otherwise return <code>None</code>. diff --git a/src/library/scala/Zero.scala b/src/library/scala/Zero.scala new file mode 100644 index 0000000000..aff1a05815 --- /dev/null +++ b/src/library/scala/Zero.scala @@ -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) + +}
\ No newline at end of file |