1
votes

Can this be done?

case class Foo[T](value: T)
case class Bar[T](value: T)

val map = mutable.Map.empty[Foo[_], Bar[_]]

map(Foo(1)) = Bar(1) // correct
map(Foo(1)) = Bar(1.1) // should cause a compiler error

It should allow any type T, as long as both Foo#T and Bar#T are the same.

1
A Map alone won't allow you to enforce that constraint, because Map takes two type parameters that are completely independent. You could define a wrapper class (around a Map) that would take a single type parameter (for both the keys and values of the underlying Map).jub0bs
@Jubobs It looks like I will have to do that. I was just hoping for a nicer way to do this, as I will be making a subclass of something purely for the purpose of type constraints.Oscar Broman

1 Answers

1
votes

You could try something like this, to force Foo's and Bar's T type parameters to be the same:

object Maps extends App {

  import scala.collection.mutable

  class C[T] {
    case class Foo(value: T)
    case class Bar(value: T)
  }

  val c = new C[Int]    
  import c._ // now Foo and Bar refer to c's types c.Foo and c.Bar

  val map = mutable.Map.empty[Foo, Bar]

  map(Foo(1)) = Bar(1) // correct
  map(Foo(1)) = Bar(1.1) // should cause a compiler error, and it does

}