Reputation: 928
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}.
Upvotes: 10
Views: 2445
Reputation: 967
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.
Upvotes: 5