3

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]

Community
  • 1
  • 1
eillasti
  • 91
  • 1
  • 4
  • @dk14, The shapeless does not help in my case, because the keys are all strings. I added a usage example and current implementation to the question. I wanted to wrap the `asInstanceOf[ValueType]` part inside a class and save the TypeTag in each class. – eillasti Dec 04 '14 at 12:45
  • 1
    Why not extend `Map[String,Any]` and add `.getTyped[V](key: String):V`, `.getTypedOpt[V](key: String): Option[V]` – Dima Dec 04 '14 at 14:20
  • This sounds more like a `Map[String, Any]` with some conveniences for casting than a heterogeneous map. – Travis Brown Dec 04 '14 at 14:21
  • @Dima, probably you are right. I first thought that I have to somehow store the type info (with TypeTag) when I put an element into the collection, so that I know to which type to cast when I pull the data from R. – eillasti Dec 04 '14 at 14:57

0 Answers0