¿Cómo definir "disyunción de tipo" (tipos de unión)?

Una forma que tienesido sugerido lidiar con definiciones dobles de métodos sobrecargados es reemplazar la sobrecarga con la coincidencia de patrones:

object Bar {
   def foo(xs: Any*) = xs foreach { 
      case _:String => println("str")
      case _:Int => println("int")
      case _ => throw new UglyRuntimeException()
   }
}

Este enfoque requiere que entreguemos la comprobación de tipo estático en los argumentos parafoo. Sería mucho mejor poder escribir

object Bar {
   def foo(xs: (String or Int)*) = xs foreach {
      case _: String => println("str")
      case _: Int => println("int")
   }
}

Puedo acercarme aEither, pero se pone feo rápido con más de dos tipos:

type or[L,R] = Either[L,R]

implicit def l2Or[L,R](l: L): L or R = Left(l)
implicit def r2Or[L,R](r: R): L or R = Right(r)

object Bar {
   def foo(xs: (String or Int)*) = xs foreach {
      case Left(l) => println("str")
      case Right(r) => println("int")
   }
}

Parece que una solución general (elegante, eficiente) requeriría definirEither3, Either4, .... ¿Alguien sabe de una solución alternativa para lograr el mismo fin? Que yo sepa, Scala no tiene "disyunción de tipo" incorporada. Además, ¿están las conversiones implícitas definidas anteriormente al acecho en la biblioteca estándar en algún lugar para que pueda importarlas?

Respuestas a la pregunta(15)

Su respuesta a la pregunta