Or Bar Yaacov
Or Bar Yaacov

Reputation: 279

Pattern matching tuple elements of equal types

I'm pattern matching on a tuple of two objects and want to match all cases where object1 is of the same type as object2, something like

(object1, object2) match {
    case (o1: T, o2: T) =>
      // Ignore same objects case
    case
    .
    .
    .
    case (_, _)
      // Here I can be certain that the two object are not of the same type
  

Upvotes: 0

Views: 182

Answers (2)

Dmytro Mitin
Dmytro Mitin

Reputation: 51723

Try

def test(object1: Any, object2: Any) = (object1, object2) match {
  case (o1, o2) if o1.getClass == o2.getClass => println("same")
  case (_, _) => println("different")
}

test(1, 2) //same
test(1, "2") //different
test(1: Any, "2": Any) //different
test(Some(1), Some("2")) //same

or

import scala.reflect.runtime.universe._
def getType[T: TypeTag](t: T): Type = typeOf[T]

def test[A: TypeTag, B: TypeTag](object1: A, object2: B) = (object1, object2) match {
  case (o1, o2) if getType(o1) == getType(o2) => println("same")
  case (_, _) => println("different")
}

test(1, 2) //same
test(1, "2") //different
test(1: Any, "2": Any) //same
test(Some(1), Some("2")) //different

or

def test[A, B](object1: A, object2: B)(implicit ev: A =:= B) = println("same")

test(1, 2) //compiles
// test(1, "2") //doesn't compile
test(1: Any, "2": Any) //compiles
// test(Some(1), Some("2")) //doesn't compile

If object1 and object2 are actually (case) objects then the easiest is

def test(object1: A, object2: A) = (object1, object2) match {
  case (o1, o2) if o1 == o2 => println("same")
  case (_, _) => println("different")
}

sealed trait A
case object B extends A
case object C extends A

test(B, B) //same
test(B, C) //different

Upvotes: 3

Pritam Kadam
Pritam Kadam

Reputation: 2527

Another variation to @Dmytro's answer: Instead of TypeTag, you could use ClassTag

import scala.reflect.ClassTag
def test[A: ClassTag, B: ClassTag](object1: A, object2: B): Unit =
  (object1, object2) match {
    case (_: A, _: A) => println("same")
    case (_, _)       => println("different")
  }

test(1, 11)   // same
test(1, "11") // different

Upvotes: 2

Related Questions