3

Im attempting to create a new operator :? on lists, which operates the same as :: except if the value if null, then the original list is returned. I have written the following, however it soon dawned that I didn't really know what I was doing....

object ImplicitList {
   implicit def extendIterator[T](i : List[T]) = new ListExtension(i)

 }

 class ListExtension[T <: Any](i : List[T]) {
  def :?[B >: T] (x: B): List[B] = if (x != null) x :: i else i
 }


 final case class :?[B](private val hd: B, private val tl: ListExtension[B]) extends ListExtension[B](tl.:?(hd))
J Pullar
  • 1,915
  • 2
  • 18
  • 30
  • 3
    The use of `null` should be avoided in Scala; use `Option` instead. `null` really only exists for interoperability with Java. – Jesper Mar 19 '12 at 13:41

1 Answers1

13

What you want is the enhance-my-library pattern. With this you can add a new method to List. Here's how that would look:

class EnhancedList[T](self: List[T]) {
  def ?:(t: T) = 
    t match {
      case null => self
      case _ => t :: self
    }
}
implicit def enhanceList[T](self: List[T]) = new EnhancedList(self)

So there's a class EnhancedList that wraps List where the new method ?: is defined, and an implicit function that converts List to EnhancedList when ?: is called. Note that you have to use ?: instead of :? because Scala's rules are such that an operator is right-associative if and only if it ends in a :.

Here's how it gets used:

scala> val l = List("a","b","c")
l: List[java.lang.String] = List(a, b, c)

scala> null ?: l
res136: List[java.lang.String] = List(a, b, c)

scala> "d" ?: l
res137: List[java.lang.String] = List(d, a, b, c)
dhg
  • 52,383
  • 8
  • 123
  • 144
  • "because Scala's rules are that an operator is right-associative if and only if it ends in a :." - just what I was looking for, thank you! – J Pullar Mar 19 '12 at 15:26