Caleb Chang
Caleb Chang

Reputation: 43

In Scala, how does pattern matching choose which case to use when using extractor objects?

I am unsure how pattern matching knows whether a StatusReply is a success or error.

val reply = StatusReply.error("my error message")
reply match
  case StatusReply.Success(v) => //
  case StatusReply.Error(msg) => //

In general, I am not certain how pattern matching chooses which case to use when using extractor objects. The unapply method in extractor objects has one argument which specifies the type of the object to be deconstructed. Im guessing that pattern matching chooses the case based on type of the argument in the unapply method. StatusReply.Success's unapply method deconstructs StatusReply[Any] and StatusReply.Error deconstructs StatusReply[_] . What is the difference between Any and _ in this situation?

This is the code of the extractor objects of StatusReply from the scala source code of StatusReply.

  object Success {

    def unapply(status: StatusReply[Any]): Option[Any] =
      if (status != null && status.isSuccess) Some(status.getValue)
      else None
  }

  object Error {

    def unapply(status: StatusReply[_]): Option[Throwable] =
      if (status != null && status.isError) Some(status.getError)
      else None
  }

Upvotes: 0

Views: 225

Answers (1)

Dmytro Mitin
Dmytro Mitin

Reputation: 51683

StatusReply[_] aka StatusReply[T] forSome { type T } is an existential type.

StatusReply[Any] is its subtype or the same type depending on whether it's invariant (StatusReply[T]) or covariant (StatusReply[+T]).

What is an existential type?

scala - Any vs underscore in generics

Understanding scala's _ vs Any/Nothing

What does `SomeType[_]` mean in scala?

What is the difference between Any and _

Difference between Future[Any] and Future[_]

You can switch on scalacOptions += "-Xprint:typer" or scalacOptions += "-Xprint:jvm" in order to see what code the pattern matching is actually translated into. There should be a sequence of asInstanceOf/isInstanceOf and unapply calls. It tries each case one by one in the order from top to bottom and the first one to succeed (i.e. where unapply returns Some or true) is the one being executed.

https://docs.scala-lang.org/tour/pattern-matching.html

https://docs.scala-lang.org/tour/extractor-objects.html

https://alvinalexander.com/scala/how-to-use-pattern-matching-scala-match-case-expressions/

"You can view the extractor objects in the scala source code of StatusReply.

Please provide significant part or the code or the link and we'll see whether there is now a difference between Any and _.

Upvotes: 3

Related Questions