import scala.reflect.Typeable def f[A: Typeable, B: Typeable](x: A | B): String = x match case a: A => "a" case b: B => "b" // works with subtyping trait T[A] { def foo(a: A): String } class Union[A: Typeable, B: Typeable](ta: T[A], tb: T[B]) extends T[A | B]{ def foo(a: A | B): String = a match case a: A => ta.foo(a) case b: B => tb.foo(b) } def t[A] = new T[A]{ def foo(a: A): String = a.toString } val union = new Union(t[String], t[Int]) println(union.foo("foo")) println(union.foo(1))