instanceOf and preconditions

It has been said that using instanceOf is redundant in Scala. However, how would you test for an object passed into a method being either one of two different types without using it?

e.g.

def mine(that: Any) {
require(that.isInstanceOf[A] || that.isInstanceOf[B])

}

With implicits.

final class IsAorB[T] private ()
object IsAorB {
  implicit val aIsAorB: IsAorB[A] = new IsAorB[A]()
  implicit val bIsAorB: IsAorB[B] = new IsAorB[B]()
}
import IsAorB._

def mine[T](that: T)(implicit evidence: IsAorB[T]): Unit = {
  require(evidence ne null) // optional
  ...
}

Or with type unions (in Dotty / Scala 3).

Your code is perfectly fine.

If you would use isInstanceOf to check whether you can use asInstanceOf, then probably pattern matching would be better.

Like, in Java, you would often do something like

if(that.isInstanceOf[A]) {

** val a = that.asInstanceOf[A]**

** …**

}

but with pattern matching, it is better to do

that match {

** case a: A => …**

}

In your case, pattern matching doesn’t look better, but if you wanted, you could do

def mine(that: Any) {
require(that match {

** case _ : A => true**

** case _ : B => true**

** case _ => false**

** }**

** )

}**

Given the situation you’re describing, sure, isInstanceOf might be correct.

That said – you should try hard to avoid getting into this situation. With a few specific exceptions (such as interfacing with JavaScript, or certain situations in Akka), winding up with a raw Any tends to mean something’s gone awry in the code, and the right solution is to examine the codepaths to avoid losing your type information in the first place.

This might be a good situation to use Either.

def mine(that: Either[A,B]) {
  that match {
    case Left(a) => ???
    case Right(b) => ???
  }
}