Existing solutions for hash map with multitype values

303 views Asked by At

I am looking for implementation of heterogeneous map. By heterogeneous map I mean a structure HMap[KeyType, Any] with defined methods:

 get[ValueType](key : KeyType] : Option[ValueType]

+(key : KeyType, value : Any) : HMap[KeyType, Any]

There are answers on Stack Overflow telling how to implement it using Manifests/ClassTags and I have a basic version:

    class TypedMap[K](

        val inner:Map[(K, TypeTag[_]), Any]){

        def +[V](key: K, value: V)(implicit tag:TypeTag[V]) = new TypedMap[K](inner + ((key, tag) -> value))

        def apply[V](key:K)(implicit tag:TypeTag[V]) = inner.apply((key, tag)).asInstanceOf[V]

        def get[V](key:K)(implicit tag:TypeTag[V]) = inner.get((key, tag)).asInstanceOf[Option[V]]

    }
    val a = new TypeMap(Map(("key1" -> 1),("key2" -> "two")))
    a.get[Int]("key1")
    a.get[String]("key2")

I wonder if there is an existing more complete implementation with additional functionality as in standard collections Map.

The usecase is reading unknown number of columns from csv/mongo/sql (some types are unknown in compile time), transforming some of the columns (their types are known in compile time), adding new ones and transferring the results map to R data.frame through rJava. In my particular case I need Map[String, Double/Int/String/Boolean/Date] if a less generic solution is somehow easier.

The short ClassTag and Manifest solutions are described in:

How do I get around type erasure on Scala? Or, why can't I get the type parameter of my collections?

Scala: What is a TypeTag and how do I use it?

I have found several small github solutions:

https://github.com/EnMAS/EnMAS-Framework/blob/master/enmas-core/src/main/scala/org/enmas/pomdp/State.scala

https://github.com/kennknowles/scala-heterogeneous-map

What I am not looking for:

  1. Compiler magic to infer in compile time the return type that is unknown in compile time - impossible

  2. Shapeless HMap – I need to distinguish between (String -> Int) and (String -> String)

  3. Inherit from scala.collections.Map – impossible because for Map[A, B] get is get[B] which is in my case get[Any]

0

There are 0 answers