Is there a way to define a generic type parameter that can be one of a small set of types? I want to define a type T that can only be one of {Int, Long, Float, Double}.
Daniel Landgon's comment above points in the right direction.
In case someone is in a hurry to click the link though:
@annotation.implicitNotFound("It can not be proven that ${T} is of type Int, Long, Float or Double")
sealed trait Foo[T]
object Foo {
implicit val intFoo: Foo[Int] = new Foo[Int]{}
implicit val LongFoo: Foo[Long] = new Foo[Long]{}
implicit val FloatFoo: Foo[Float] = new Foo[Float]{}
implicit val DoubleFoo: Foo[Double] = new Foo[Double]{}
}
With:
def bar[T](t: T)(implicit ev: Foo[T]): Unit = println(t)
We get:
bar(5) // res: 5
bar(5.5) // res: 5.5
bar(1.2345F) // res: 1.2345
bar("baz") // Does not compile. Error: "It can not be proven that String is of type Int, Long, Float or Double"
bar(true) // Does not compile. Error: "It can not be proven that Boolean is of type Int, Long, Float or Double"
This could also be achieved with Miles Sabin's union type as provided in his shapeless library.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With