I\'m often writing code that compares two objects and produces a value based on whether they are the same, or different, based on how they are different.
So I might writ
I think you're asking two slightly different questions.
One question is how to use "or" in switch statements. || doesn't work; | does. And you can't use variables in that case (because in general they might match different types, which renders the type confusing). So:
def matcher[T](a: (T,T)) = {
a match {
case (Some(x),Some(y)) => "both"
case (Some(_),None) | (None,Some(_)) => "either"
case _ => "none"
}
}
Another question is how to avoid having to do this over and over, especially if you want to be able to get at the value in the tuple. I've implemented a version here for Option, but you could use an unwrapped tuple and a boolean.
One trick to achieve this is that to prewrap the values before you start matching on it, and then use your own matching constructs that do what you want. For instance,
class DiOption[+T] {
def trinary = this
}
case class Both[T](first: T, second:T) extends DiOption[T] { }
case class OneOf[T](it: T) extends DiOption[T] { }
case class Neither() extends DiOption[Nothing] { }
implicit def sometuple2dioption[T](t2: (Option[T],Option[T])): DiOption[T] = {
t2 match {
case (Some(x),Some(y)) => Both(x,y)
case (Some(x),None) => OneOf(x)
case (None,Some(y)) => OneOf(y)
case _ => Neither()
}
}
// Example usage
val a = (Some("This"),None)
a trinary match {
case Both(s,t) => "Both"
case OneOf(s) => "Just one"
case _ => "Nothing"
}