user1094206
user1094206

Reputation: 928

Restrict Scala type to be one of a set of types

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

Answers (1)

cmhteixeira
cmhteixeira

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

Related Questions