Ian Juma
Ian Juma

Reputation: 107

Scala Option pattern matching with case class

I get error: value id is not a member of Nothing with case Some(x) => x.id. This should not have evaluated to a Some type.

case class UserDbEntry(id: Int, username: String)

val users = List()
val lastTableIds = "user.1::paypal.1"
val lastUserId   = lastTableIds.split("::")(0).split("\\.")(1)

//This does not compile
val id = users.lastOption match {
  case Some(x) => x.id
  case None => lastUserId
}

//This compiles
def getLastFetchId(x: Option[UserDbEntry]) = x match {
  case Some(user) => user
  case None => 1
}

But with the List defined with an explicit type of List[UserDbEntry] this is fine, in that case the compiler infers this successfully. I guess it has to do with compiler inferencing; If I am not wrong. Just that I expected an error in line with x not being a member of type String if there was a type mismatch.

What exactly is going on here?

Upvotes: 0

Views: 461

Answers (1)

hasumedic
hasumedic

Reputation: 2167

When you declare:

val users = List()

The compiler infers:

val users: List[Nothing] = List()

Nothing does not have an id property. But when you specify that users is a List[UserDbEntry] and call lastOption, then the compiler can understand that the element within the Option is a UserDbEntry, which has an id property, hence compiling just fine. Take into account that an empty List will return None, which is an Option[Nothing].

Upvotes: 4

Related Questions