summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2009-10-26 20:56:14 +0000
committerPaul Phillips <paulp@improving.org>2009-10-26 20:56:14 +0000
commit35a8ab3cddd27550ea8f3329483b065a2d83fae8 (patch)
treed69e27708e5371fec356ce99835e794e65afa7d5 /src
parent0b16c1266296e93339f56054f1b5e3f5908d3e55 (diff)
downloadscala-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.
Diffstat (limited to 'src')
-rw-r--r--src/library/scala/Option.scala6
-rw-r--r--src/library/scala/Zero.scala75
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