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.
Related
I am writing a static analysis using the OPAL framework.
Therefore, I invoke an abstract interpretation of a method, where I have upper type bounds for the passed parameters as FieldTypes.
It looks like this:
BaseAI.perform(classFile, caller, domain)(parameters)
Where parameters is an IndexedSeq[FieldType].
This results in the following type error:
type mismatch; found : scala.collection.immutable.IndexedSeq[org.opalj.br.FieldType] required: Option[scala.collection.IndexedSeq[domain.DomainValue]] (which expands to) Option[scala.collection.IndexedSeq[domain.Value]]
Is there any possibility to convert my FieldTypes to DomainValues?
Can I use
domain.ClassValue(origin, identifiedFieldType)
to convert it, even if the type is e.g. an int? (since int is not a class)
If yes, is there a method, which computes the origin index for method parameters?
Part one of the question:
You can use:
domain.TypedValue(origin, parameterType)
In this case parameterType can be "any type".
Part two of the question:
The following function defined by the package object org.opalj.ai can be used compute the correct value index.
def parameterToValueIndex(
isStaticMethod: Boolean,
descriptor: MethodDescriptor,
parameterIndex: Int
): Int = {
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]()
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.
Scala-lang reference 5.5.1 and 6.6.1 gave me the impression that a default parameter would be able to refer to a previously evaluated one:
class Test(val first: String, val second: String = first)
but from experimenting it seems the only way to do this is to use the form:
class Test(val first: String)(val second: String = first)
and then define an auxiliary constructor or a creational companion class to avoid specifying the second set of brackets when creating. I don't really understand how this second constructor works, it looks like a curried function so I might guess that it is necessary to evaluate first independently of second, is this correct? Is this form necessary or is there some syntatic sugar I can use to tweak the first constructor into doing what I want?
As Travis Brown points out, you can indeed only refer to a previous argument in a default expression when it is from a previous argument list (so you do need to currify).
Now, regarding your particular use case, default arguments and method overloading are sometimes two ways of achieving the same thing.
I think the simplest solution to your scenario is simply to define Test as follows:
class Test(val first : String, val second : String) {
def this(f : String) = this(f, f)
}
If you want to make it more complicated, an alternative way, using a companion object:
class Test(val first : String)(val second : String = first)
object Test {
def apply(f : String) = new Test(f)
def apply(f : String, s : String) = new Test(f)(s)
}
(A small difference is that now you create objects without new.)
What you cannot do, is define it as:
class Test(val first : String)(val second : String = first) {
def this(f : String, s : String) = this(f)(s)
}
...because the curried version gets translated into (among other things) a method with the same signature as the overloaded contructor.
From 5.3 of the spec:
The scope of a formal value parameter includes all subsequent
parameter sections and the template t.
Regular methods are the same, by the way (from 4.6):
The scope of a formal value parameter name x comprises all
subsequent parameter clauses, as well as the method return type and
the function body, if they are given.
I.e., whether you've got a constructor or an ordinary method, a value parameter name isn't in scope in its own parameter clause. In your second version the constructor has two parameter clauses, and first is only in scope in the second. See 5.3 for more detail about multiple parameter clauses.
Working in Scala-IDE, I have a Java library, in which one of the methods receives java.lang.Object. And I want to map a list of Int values to it. The only solution that works is:
val listOfInts = groupOfObjects.map(_.getNeededInt)
for(int <- listOfInts) libraryObject.libraryMethod(int)
while the following one:
groupOfObjects.map(_.getNeededInt).map(libraryMethod(_)
and even
val listOfInts = groupOfObjects.map(_.getNeededInt)
val result = listOfInts.map(libraryObject.libraryMethod(_))
say
type mismatch; found : Int required: java.lang.Object Note: an
implicit exists from scala.Int => java.lang.Integer, but methods
inherited from Object are rendered ambiguous. This is to avoid a
blanket implicit which would convert any scala.Int to any AnyRef. You
may wish to use a type ascription: x: java.lang.Integer.
and something like
val result = listOfInts.map(libraryObject.libraryMethod(x => x.toInt))
or
val result = listOfInts.map(libraryObject.libraryMethod(_.toInt))
does not work also.
1) Why is it happening? As far as I know, the for and map routines do not differ that much!
2) Also: what means You may wish to use a type ascription: x: java.lang.Integer? How would I do that? I tried designating the type explicitly, like x: Int => x.toInt, but that is too erroneus. So what is the "type ascription"?
UPDATE:
The solution proposed by T.Grottker, adds to it. The error that I am getting with it is this:
missing parameter type for expanded function ((x$3) => x$3.asInstanceOf[java.lang.Object])
missing parameter type for expanded function ((x$3) => x$3.asInstanceOf{#null#}[java.lang.Object]{#null#}) {#null#}
and I'm like, OMG, it just grows! Who can explain what all these <null> things mean here? I just want to know the truth. (NOTE: I had to replace <> brakets with # because the SO engine cut out the whole thing then, so use your imagination to replace them back).
The type mismatch tells you exactly the problem: you can convert to java.lang.Integer but not to java.lang.Object. So tell it you want to ask for an Integer somewhere along the way. For example:
groupOfObjects.map(_.getNeededInt: java.lang.Integer).map(libraryObject.libraryMethod(_))
(The notation value: Type--when used outside of the declaration of a val or var or parameter method--means to view value as that type, if possible; value either needs to be a subclass of Type, or there needs to be an implicit conversion that can convert value into something of the appropriate type.)