How to create com.google.common.collect.HashBiMap - scala

val map = com.google.common.collect.HashBiMap[String, Int].create()
gives the compile error
object com.google.common.collect.HashBiMap is not a value
How do I create an instance of com.google.common.collect.HashBiMap?

The class HashBiMap has two generic type parameters. Its companion object (the object that shares the name HashBiMap) does not have type parameters, because it's an object, not a class. When you call HashBiMap.create, you're calling the create method on the companion object. So, the expression HashBiMap[String, Int].create doesn't make any sense, because that HashBiMap refers to the object, which isn't parameterized. Its create method, does take two type parameters. So HashBiMap.create[String, Int]() does what you want. It returns a HashBiMap[String, Int].
In case you're more familiar with Java: The expression you've given is akin to something like Arrays<Integer>.asList(1,2,3), whereas the correct expression would be Arrays.<Integer>asList(1,2,3).

I think it's just a matter of where you put the type parameters. Try
val map = HashBiMap.create[String, Int]()

Related

Given a Type, create an Option Type that contains it

Given a Type named inner, I would like to create a new Type that represents an Option containing a type of the same type as inner.
For example, the signature of a method that would do this may look something like:
def createOptionType(inner: Type): Type = {
typeOf[Option[inner]] // this line is pseudocode
}
This answer helps partially, but makes use of a generic method, whereas in this case I have a concrete type passed in, making generics unuseable.
You can use scala.reflect.runtime.universe.appliedType for that:
import scala.reflect.runtime.universe._
def createOptionType(inner: Type): Type =
appliedType(typeOf[Option[_]], inner)

Scala Compile Error

I have trouble in building the following code:
type graph_t = scala.collection.mutable.Map[Long, (Long, Float)];
var graph : graph_t = graph_t();
However, it does work by replacing the graph_t() with the original type:
var graph : graph_t = scala.collection.mutable.Map[Long, (Long, Float)] ();
Any answer will be appreciated.
Scala knows two namespaces: types and values. Types define what values are capable of, and values are the things you call methods on.
graph_t() is a method call (the apply method), but you did not define a value called graph_t, you defined a type called graph_t, and you cannot call methods on types.
The reason scala.collection.mutable.Map[Long, (Long, Float)] () works is because scala.collection.mutable.Map is both a type and a value.
That's interesting. Try this:
type s = String;
var x = s()
You get the same error: not found.
That's is because the name of the class is both the name of the type and the name of the constructor, but the name of a type is not necessarily the name of a constructor.
In this case, the function Map actually constructs a concrete implementation of the Map abstract class.

Scala reflection on function parameter names

I have a class which takes a function
case class FunctionParser1Arg[T, U](func:(T => U))
def testFunc(name1:String):String = name1
val res = FunctionParser1Arg(testFunc)
I would like to know the type signature information on the function from inside the case class. I want to know both the parameter name and type. I have had success in finding the type using the runtime mirror objects, but not the name. Any suggestions?
Ok, let's say you got the symbol for the instance func points to:
import scala.reflect.runtime.universe._
import scala.reflect.runtime.{currentMirror => m}
val im = m reflect res.func // Instance Mirror
You can get the apply method from its type members:
val apply = newTermName("apply")
val applySymbol = im.symbol.typeSignature member apply
And since we know it's a method, make it a method symbol:
val applyMethod = applySymbol.asMethod
It's parameters can be found through paramss, and we know there's only one parameter on one parameter list, so we can get the first parameter of the first parameter list:
val param = applyMethod.paramss(0)(0)
Then what you are asking for is:
val name = param.name.decoded // if you want "+" instead of "$plus", for example
val type = param.typeSignature
It's possible that you think that's the wrong answer because you got x$1 instead of name1, but what is passed to the constructor is not the named function testFunc, but, instead, an anonymous function representing that method created through a process called eta expansion. You can't find out the parameter name of the method because you can't pass the method.
If that's what you need, I suggest you use a macro instead. With a macro, you'll be able to see exactly what is being passed at compile time and get the name from it.

Return values from a generic Option Array in Scala

I am having some difficulty making my function generic, and need some help. I have an array that takes Option's of T where T is a Fractional.
In F#, there is a function "choose" which strips None's from a collection of Options. In scala, I am trying to use "flatten", but it does not work with a generic type.
my code is
var arr = Array.fill(capacity)(None :Option[T])
...
and later I try to get values of the Some's :
var flat = arr.flatten
error is:
error: could not find implicit value for parameter m: scala.reflect.ClassManifest[U]
val flat = arr.flatten
i am a complete scala noob, and maybe should not play with generics :)
how do i make this work?
Thanks!
The problem is that you are trying to create a new generic array, and your method doesn't know how because arrays require type information. You should then add a ClassManifest context bound so that the array knows how to create itself:
def flat[T: ClassManifest](bumpy: Array[Option[T]]): Array[T] = bumpy.flatten
val fish = Array(Some("salmon"), None, Some("haddock"))
flat(fish) // Prints Array(salmon, haddock)
Note that if you try to pass the array in directly to the method, it will get confused trying to figure out what type it is; you need the assignment for a val to let it know that the array itself contains all the information about its type, and then flat should take its type from the array.

Scala type alias including companion object [beginner]

I'd like to write a type alias to shorten, nice and encapsulated Scala code.
Suppose I got some collection which has the property of being a list of maps, the value of which are tuples.
My type would write something like List[Map[Int, (String, String)]], or anything more generic as my application allows it. I could imagine having a supertype asking for a Seq[MapLike[Int, Any]] or whatever floats my boat, with concrete subclasses being more specific.
I'd then want to write an alias for this long type.
class ConcreteClass {
type DataType = List[Map[Int, (String, String)]]
...
}
I would then happily use ConcreteClass#DataType everywhere I can take one, and use it.
Now suppose I add a function
def foo(a : DataType) { ... }
And I want to call it from outside with an empty list.
I can call foo(List()), but when I want to change my underlying type to be another type of Seq, I'll have to come back and change this code too. Besides, it's not very explicit this empty list is intended as a DataType. And the companion object does not have the associated List methods, so I can't call DataType(), or DataType.empty. It's gonna be even more annoying when I need non-empty lists since I'll have to write out a significant part of this long type.
Is there any way I can ask Scala to understand my type as the same thing, including companion object with its creator methods, in the interest of shortening code and blackboxing it ?
Or, any reason why I should not be doing this in the first place ?
The answer was actually quite simple:
class ConcreteClass {
type DataType = List[String]
}
object ConcreteClass {
val DataType = List
}
val d = ConcreteClass.DataType.empty
This enables my code to call ConcreteClass.DataType to construct lists with all the methods in List and little effort.
Thanks a lot to Oleg for the insight. His answer is also best in case you want not to delegate to List any call to ConcreteClass.DataType, but control precisely what you want to allow callers to do.
What about this?
class ConcreteClass {
type DataType = List[String]
}
object DataType {
def apply(): ConcreteClass#DataType = Nil
}
//...
val a = DataType()