Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pattern match empty ArrayBuffer

Is there any special case class for representing an empty ArrayBuffer that can be used in pattern matching similar to Nil for lists?

Also why this works:

scala> collection.mutable.ArrayBuffer.empty == Nil
res11: Boolean = true

While this does not:

scala> collection.mutable.ArrayBuffer() match { case Nil => 1 }
<console>:8: error: pattern type is incompatible with expected type;
 found   : scala.collection.immutable.Nil.type
 required: scala.collection.mutable.ArrayBuffer[Nothing]

UPDATE

After giving it some thought I presume there is no such a case class. While existence of Nil is vital for List to work, no special structure of this kind is needed for arrays.

I've found a workaround for empty match check that might work in most cases:

collection.mutable.ArrayBuffer(2) match { 
  case collection.mutable.ArrayBuffer(v, _*) => v * 2
  case _ => 0 
}

I first check if array has at least one element and otherwise it should be empty. Also as it turns out I could just use ArrayBuffer.isEmpty instead of pattern match.

like image 329
src091 Avatar asked Jun 16 '14 15:06

src091


2 Answers

Jasper-M provided a good answer to your second question (why == works but pattern matching fails).

As to your first, there is no equivalent to Nil for ArrayBuffer. The reason is that List is defined using scala's notion of Algebraic Data Types (ADT), while ArrayBuffer is not.

Take a look at the source for ArrayBuffer. It's implemented as a regular class, whereas List is implemented as an abstract class with two subclasses: a case object Nil, and a case class ::.

These case classes are what allow you to pattern match on List. Since there's no equivalent for ArrayBuffer, you cannot pattern match.

like image 169
cdk Avatar answered Nov 03 '22 00:11

cdk


scala> collection.mutable.ArrayBuffer.empty == Nil
res11: Boolean = true

The reason this is true can be found by looking at the documentation of the equals method:

true if that is a sequence that has the same elements as this sequence in the same order, false otherwise

For instance:

scala> val buffer = collection.mutable.ArrayBuffer.empty[Int]
buffer: scala.collection.mutable.ArrayBuffer[Int] = ArrayBuffer()

scala> buffer.append(4)

scala> buffer == List(4)
res1: Boolean = true

So that has nothing to do with pattern matching.

like image 29
Jasper-M Avatar answered Nov 03 '22 00:11

Jasper-M