5

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.

1
  • 1
    ArrayBuffer.isEmpty seems more right for a non-ADT! ...or just toList your ArrayBuffer, unless it's too expensive, and work on that. Commented Jun 16, 2014 at 21:57

3 Answers 3

5

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.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for confirming my own thoughts on this.
2
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.

1 Comment

By the way, some people out there think that scala lacks notion of type safe equals, which will not allow things like op's example, or, say, 1 == 1.0
0

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.

2 Comments

This answer might be more appropriate as an edit to your original question. Also, why are you not using ArrayBuffer#isEmpty?
Ok, I'll edit my question instead. Wow, did not know ArrayBuffer has such a property.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.