- About Scala
- Documentation
- Code Examples
- Software
- Scala Developers
How do I create a Map type that allows multiple types for both keys and values?
Sat, 2010-06-05, 18:48
I'm trying to create a Map type so something like the below is possible:
VariantMap(1) = "Test"
VariantMap("a") = 42
My current code requires me to access the map like this:
VariantMap[String](1)
Current code:
object VariantMap {
import scala.reflect.Manifest
private var _map= Map.empty[Any,(Manifest[_], Any)]
def update[T](name: Any, item: T)(implicit m: Manifest[T]) {
_map = _map(name) = (m, item)
}
def apply[T](key:Any)(implicit m : Manifest[T]): Option[T] = {
val o = _map.get(key)
o match {
case Some((om: Manifest[_], s : Any)) => if (om <:< m)
Some(s.asInstanceOf[T]) else None
case _ => None
}
}
}
Is something like what I am trying to do possible?
Thanks for your time - Derek
Sat, 2010-06-05, 20:57
#2
Re: How do I create a Map type that allows multiple types for
On Saturday June 5 2010, myspam456 wrote:
> I realized I wasn't clear in what I meant in my first email.
I think it would be best if you asked either on Stack Overflow or here,
but not start in one place and then switch to the other.
While this is not exactly apropos your question, I'll start with it to
provide some background: When you create a Map in a manner equivalent
to this:
val m1 = Map(1 -> "one", "one" -> 1)
The compiler finds an upper bound (ideally the least upper bound) of all
the keys and (separately, of course) of all the values and uses those
as the inferred key and value type for the resulting Map:
m1: scala.collection.immutable.Map[Any,Any] = Map((1,one), (one,1))
There's no other way in a statically typed language to accommodate such
a variety of types.
> I would like to access the map like this:
>
> val temp = VariantMap(1)
>
> and have temp by of type Option[String]
>
> Currently if I try to do that the return type is Option[Nothing].
First, I believe you want to define a class, not an object.
Secondly, you may be unaware that the type parameters T in update(...)
and apply(...) are unrelated. If you defined a class in this manner:
class VariantMap[T] { ... }
Then every occurrence of T within that class (when not shadowed locally)
would be co-referrent to the actual type used when instantiating the
class. You'd still need to remove the type parameters T from update and
apply to meet the "not shadowed locally" criterion.
As it stands, because apply(...) has an unbounded type parameter and
uses that in its return, nothing is statically known about it and the
compiler infers Nothing for T. If you used T in the formal arguments,
then each use of apply would supply some type information derived
(statically) from the value passed. But without that, you're asking the
compiler (or the runtime) to know the unknowable. (The use of Manifest
is entirely a red herring here.)
Randall Schulz
> On Sat, Jun 5, 2010 at 12:48 PM, Derek N. wrote:
> > I'm trying to create a Map type so something like the below is
> > possible:
> >
> > VariantMap(1) = "Test"
> > VariantMap("a") = 42
> >
> > My current code requires me to access the map like this:
> >
> > VariantMap[String](1)
> >
> > Current code:
> >
> > object VariantMap {
> > import scala.reflect.Manifest
> >
> > private var _map= Map.empty[Any,(Manifest[_], Any)]
> >
> > def update[T](name: Any, item: T)(implicit m: Manifest[T]) {
> > _map = _map(name) = (m, item)
> > }
> >
> > def apply[T](key:Any)(implicit m : Manifest[T]): Option[T] = {
> > val o = _map.get(key)
> > o match {
> > case Some((om: Manifest[_], s : Any)) => if (om <:< m)
> > Some(s.asInstanceOf[T]) else None
> > case _ => None
> > }
> > }
> > }
> >
> > Is something like what I am trying to do possible?
Sat, 2010-06-05, 21:07
#3
Re: How do I create a Map type that allows multiple types for
why not simply new HashMap[_,_] ? what do you need the manifest for?
Sat, 2010-06-05, 21:17
#4
Re: How do I create a Map type that allows multiple types for
What you want is not possible with scala.
Linas.
On Sat, 2010-06-05 at 14:11 -0500, myspam456 wrote:
> I realized I wasn't clear in what I meant in my first email.
>
>
> I would like to access the map like this:
>
>
> val temp = VariantMap(1)
>
>
> and have temp by of type Option[String]
>
>
> Currently if I try to do that the return type is Option[Nothing].
>
>
> Thanks
>
> On Sat, Jun 5, 2010 at 12:48 PM, Derek N. wrote:
>
> I'm trying to create a Map type so something like the below is
> possible:
>
> VariantMap(1) = "Test"
> VariantMap("a") = 42
>
> My current code requires me to access the map like this:
>
> VariantMap[String](1)
>
> Current code:
>
> object VariantMap {
> import scala.reflect.Manifest
>
> private var _map= Map.empty[Any,(Manifest[_], Any)]
>
> def update[T](name: Any, item: T)(implicit m: Manifest[T]) {
> _map = _map(name) = (m, item)
> }
>
> def apply[T](key:Any)(implicit m : Manifest[T]): Option[T] =
> {
> val o = _map.get(key)
> o match {
> case Some((om: Manifest[_], s : Any)) => if (om <:< m)
> Some(s.asInstanceOf[T]) else None
> case _ => None
> }
> }
> }
>
> Is something like what I am trying to do possible?
>
> Thanks for your time - Derek
> --
> View this message in context:
> http://scala-programming-language.1934581.n4.nabble.com/How-do-I-create-...
> Sent from the Scala - User mailing list archive at Nabble.com.
>
>
Sat, 2010-06-05, 21:27
#5
Re: How do I create a Map type that allows multiple types for
*storing* anything as key and value in the same map is possible.
(Map[_, _])
making the compiler aware of what value has which type is not. you have to manually cast the returned option. but why would you want that? why not use a simple field in this case?
Linas schrieb:
making the compiler aware of what value has which type is not. you have to manually cast the returned option. but why would you want that? why not use a simple field in this case?
Linas schrieb:
What you want is not possible with scala. Linas. On Sat, 2010-06-05 at 14:11 -0500, myspam456 wrote:I realized I wasn't clear in what I meant in my first email. I would like to access the map like this: val temp = VariantMap(1) and have temp by of type Option[String] Currently if I try to do that the return type is Option[Nothing]. Thanks On Sat, Jun 5, 2010 at 12:48 PM, Derek N. myspam456 [at] gmail [dot] com (<myspam456 [at] gmail [dot] com>) wrote: I'm trying to create a Map type so something like the below is possible: VariantMap(1) = "Test" VariantMap("a") = 42 My current code requires me to access the map like this: VariantMap[String](1) Current code: object VariantMap { import scala.reflect.Manifest private var _map= Map.empty[Any,(Manifest[_], Any)] def update[T](name: Any, item: T)(implicit m: Manifest[T]) { _map = _map(name) = (m, item) } def apply[T](key:Any)(implicit m : Manifest[T]): Option[T] = { val o = _map.get(key) o match { case Some((om: Manifest[_], s : Any)) => if (om <:< m) Some(s.asInstanceOf[T]) else None case _ => None } } } Is something like what I am trying to do possible? Thanks for your time - Derek -- View this message in context: http://scala-programming-language.1934581.n4.nabble.com/How-do-I-create-a-Map-type-that-allows-multiple-types-for-both-keys-and-values-tp2244431p2244431.html Sent from the Scala - User mailing list archive at Nabble.com.
Sat, 2010-06-05, 21:57
#6
Re: How do I create a Map type that allows multiple types for b
You aren't too specific about what you want to allow, but one thing you can do is use a heterogeneous map class:
http://github.com/harrah/up/blob/master/TypedMap.scala
http://github.com/harrah/up/blob/master/TypedMapTest.scala
Sample usage:
// map that allows only:
// String -> Int
// String -> Boolean
class TypeMap1 extends TypeMap {
implicit val StrToBool = new TypeMapping[String, Boolean] {}
implicit val StrToInt = new TypeMapping[String, Int] {}
}
val m = new TypeMap1
import m._
m("a") = 3
m("a") = true
// compile error
//m("a") = "string"
assert( m.getOr("a", 5) == 3)
assert( m.getOr("b", 5) == 5)
assert( m.getOr("a", false) == true)
assert( m.getOr("b", false) == false)
// compile errors
//m.getOr("a", 'z')
//m.getOr(3, true)
-Mark
On Saturday 05 June 2010, myspam456 wrote:
> I realized I wasn't clear in what I meant in my first email.
>
> I would like to access the map like this:
>
> val temp = VariantMap(1)
>
> and have temp by of type Option[String]
>
> Currently if I try to do that the return type is Option[Nothing].
>
> Thanks
>
> On Sat, Jun 5, 2010 at 12:48 PM, Derek N. wrote:
>
> >
> > I'm trying to create a Map type so something like the below is possible:
> >
> > VariantMap(1) = "Test"
> > VariantMap("a") = 42
> >
> > My current code requires me to access the map like this:
> >
> > VariantMap[String](1)
> >
> > Current code:
> >
> > object VariantMap {
> > import scala.reflect.Manifest
> >
> > private var _map= Map.empty[Any,(Manifest[_], Any)]
> >
> > def update[T](name: Any, item: T)(implicit m: Manifest[T]) {
> > _map = _map(name) = (m, item)
> > }
> >
> > def apply[T](key:Any)(implicit m : Manifest[T]): Option[T] = {
> > val o = _map.get(key)
> > o match {
> > case Some((om: Manifest[_], s : Any)) => if (om <:< m)
> > Some(s.asInstanceOf[T]) else None
> > case _ => None
> > }
> > }
> > }
> >
> > Is something like what I am trying to do possible?
> >
> > Thanks for your time - Derek
I would like to access the map like this:
val temp = VariantMap(1)
and have temp by of type Option[String]
Currently if I try to do that the return type is Option[Nothing].
Thanks
On Sat, Jun 5, 2010 at 12:48 PM, Derek N. <myspam456 [at] gmail [dot] com> wrote: