Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why `Nil` is defined as `case object`

In scala source, I found:

case object Nil extends List[Nothing] {
    ...
}

I can't understand why it is declared as case object rather than object?

I found this question [ Difference between case object and object ] is useful, and I guess this reason is the key:

default implementations of serialization

because we often send list of data to another actor, so Nil must be serializable, right?


With the provided answers(thanks), I try to write some code to verify it:

trait MyList[+T]

object MyNil extends MyList[Nothing]

val list: MyList[String] = MyNil

list match {
  case MyNil => println("### is nil")
  case _ => println("### other list")
}

You can see MyNil is not case object, but I can still use it in pattern matching. Here is the output:

### is nil

Do I misunderstand something?

like image 471
Freewind Avatar asked Jun 30 '14 15:06

Freewind


2 Answers

In general for immutable data, the question should never be "why is this a case object (or class)" but rather "Can I make this a case object?". With a few small exceptions (mostly due to inheritance), data elements in Scala should be immutable, and should be implemented via case classes/objects. Given that, implementing Nil and :: as a case object and case class (respectively) is just standard practice, for which there is no downside.

like image 108
Dave Griffith Avatar answered Sep 20 '22 03:09

Dave Griffith


As mentioned in the comments of that linked question, one thing you get is a prettier .toString result

scala> MyNil.toString
res0: String = MyNil$@51aa572b

scala> case object MyNil2 extends MyList[Nothing]
defined module MyNil2

scala> MyNil2.toString
res2: String = MyNil2

scala> Nil.toString
res1: String = List()
like image 38
Bobby Avatar answered Sep 21 '22 03:09

Bobby