title: How to implement a collection of key, value pairs with mixed but restricted types for values
body: <p>A use case here is to imagine a config object, that is a collection of key-value pairs. </p>
  
  <p>I would like a to create a type representing this collection of key, value pairs. And I'd also like to have the values be of varied types. Further, I'd like to keep those key, value pairs in a single collection, despite the values being of different types. But I don't want to allow the values to by of any type at all. Finally, I'd like to be able to recover the value for a given key. (Bonus points, I'd like to ensure keys are unique)</p>
  
  <p>Something like:</p>
  
  <pre><code>trait Property
  case class SProperty(name: String, value:String) extends Property
  case class DProperty(name: String, value:Double) extends Property
  case class IProperty(name: String, value:Int) extends Property
  
  case class Properties(props: List[Property]) {
    def getValueByName(name: String) = {
      props.find(p =&gt; p.name == name).map(p =&gt; p.value)
    } 
  }
  </code></pre>
  
  <p>And this works ok, but it creates an ugly API. For example:</p>
  
  <pre><code>val properties = Properties(
    List(
      Property("some name", "some value"),
      Property("another name", "another value")
    )
  )
  </code></pre>
  
  <p>If I have a test that checks:</p>
  
  <pre><code>properties.getValueByName("some name").getOrElse(None) shouldBe "some value"
  </code></pre>
  
  <p>the test will fail with </p>
  
  <pre><code>SProperty("some value") is not equal to "some value"
  </code></pre>
  
  <p>I considered using a shapeless HList, however that would allow <code>Properties</code> to take on any type. I only want <code>Property</code> types in the collection, and I want the values in those to be restricted to types <code>String | Double | Int</code>. </p>
  
  <p>Is there a better way to define this collection of key, value pairs that allows for a specific set of value types and that can provide me with a <code>.get</code> method?</p>
  
  <p>Is there a better way to define my <code>getValueByName</code> method such that it returns the underlying value and not the wrapped value?</p>
  
  <p>One approach is to write the getter like this:</p>
  
  <pre><code>def getValueByName[T](name: String): Option[Any] = {
    Properties.find(p =&gt; p.name == name).map {
      case Property(_, SProperty(v)) =&gt; Some(v)
      case Property(_, DProperty(v)) =&gt; Some(v)
      case Property(_, IProperty(v)) =&gt; Some(v)
      case _ =&gt; None
  }
  </code></pre>
  
  <p>}</p>
  
  <p>But this starts to be a lot of places to modify the code to add a new type allowed for the property values. Returning an <code>Option[Any]</code> seems wrong. And to use the getter, you'd need to know the type of the value ahead of time. That may be good, but it may be a hassle. </p>
  
  <p>I was also unable to find an acceptable approach using typeclasses, but I admit that I'm not deeply experienced with writing typeclasses.</p>