0

Would someone help me understand why this does not work? Scala version 2.10

object ColorEnum {
  sealed trait Color
  case object Red extends Color
  case object Blue extends Color
  case object Green extends Color
}

Create a Map that accepts a Color as the Key and a String as a value

val colorMap = mutable.HashMap[ColorEnum.Color, String]()

Put an item on Map using ColorEnum as Key

colorMap.put(ColorEnum.Red, "Foo")

This throws an exception

error: type mismatch
found: ColorEnum.Red.type
required: ColorEnum.Color

I must be missing something with my understanding of how this should work.

Thanks

user943583
  • 69
  • 2
  • 9
  • I already updated my answer by providing link to other related topic with example of how to use case class as a key. – Kamil Jun 28 '16 at 11:21
  • 2
    This compiles for me. Are you sure this the code you're using? – Yuval Itzchakov Jun 28 '16 at 12:03
  • If I define the trait and the case objects outside of the `object ColorEnum` hierarchy. Then define a map as `val colorMap = mutable.HashMap[Color, String]()` it works using `colorMap.put(Red, "Foo")`. Creating the sealed trait Color and case objects within ColorEnum does not work then (at least for me). – user943583 Jun 28 '16 at 12:45
  • The original code does not work in the shell, but it does in a worksheet.Very frustrating – user943583 Jun 28 '16 at 12:59

1 Answers1

2

Summary:
As of Scala 2.11 (and all preceding versions of Scala back to 2.8) Map's key is the type A in Map[A, +B]. And Map doesn't allow covariance when specifying the key; i.e. notice how the A doesn't have a plus (+) sign preceding it.

Here's a specific StackOverflow answer which addresses the details: https://stackoverflow.com/a/678637/501113

Details:
Your trait, Color, is the type by which you are defining your Map. And you define three descendants of the Color trait. Then, you are attempting to insert these descendants of the Color trait (as opposed to an instance of the trait itself) into the Map. And the type definition of Map only allows direct instances of the Color trait, not descendants (defined via extends or with).

You could use .asInstanceOf[Color] when inserting the descendant keys into the Map in order to conform to the Map's type requirement for the key. However, be warned using this approach is considered an undesirable code smell.

Bonus:
It appears you are attempting to define your own strongly typed enumeration. Please look at this answer to a related question regarding defining enumerations in Scala.

Community
  • 1
  • 1
chaotic3quilibrium
  • 5,661
  • 8
  • 53
  • 86