Given a java class with two methods (taken from mockito):
OngoingStubbing<T> thenReturn(T value);
OngoingStubbing<T> thenReturn(T value, T... values);
If I invoke from scala with
....thenReturn("something")
I get an error:
Description Resource Path Location Type
ambiguous reference to overloaded definition, both method thenReturn in trait OngoingStubbing of type (x$1: java.lang.Object, x$2: <repeated...>[java.lang.Object])org.mockito.stubbing.OngoingStubbing[java.lang.Object] and method thenReturn in trait OngoingStubbing of type (x$1: java.lang.Object)org.mockito.stubbing.OngoingStubbing[java.lang.Object] match argument types (java.lang.String)
And I cannot figure out how to fix this.
This is a known Scala-Java interoperability problem, though it's unfortunately not in the FAQ. Here's the Scala ticket describing the problem. Essentially, both methods are applicable when you give a single argument, and the Scala compiler currently doesn't have any heuristic to decide which one is "more specific". Alexey Romanov's approach to always use the varargs version is a good workaround:
thenReturn("something", Nil: _*)
There is also a question running into a similar problem with JCommander. One of the answers there gives a clever workaround using structural types. This approach will use reflection behind the scenes, so you may or may not want to go that direction. For your use case, it would look something like:
type useSingleArgVersion = { def thenReturn(value: AnyRef): OngoingStubbing }
(...).asInstanceOf[useSingleArgVersion].thenReturn("something")
Finally, there is a similar question running into a similar problem with mokito. It doesn't really provide any workarounds, but it does describe the problem in a bit more detail, if you're interested in the reason this happens.
If calling the vararg version is acceptable,
thenReturn("something", Nil: _*)
Can't think of a way to call the method without varargs right now.
These answers are all to the wrong question. The difference is subtle, but this is not the same issue as the one in the linked ticket. That one does require unreasonable gymnastics to call the non-varargs method. For this one, the following is enough.
thenReturn[String]("something")
Or, if you didn't want to do that for some reason, you don't need the type alias and the cast. You can use a structural type ascription directly.
(this: { def thenReturn[T](s: T): OngoingStubbing[T] }).thenReturn("something")
The issue here is type inference at the intersection of overloading and polymorphism - one method is more specific, but scalac doesn't figure out which. The issue in SI-2991 is genuine ambiguity due to an interaction between overloading and tuple conversion - neither is more specific.
Assuming others will find this question when having the overloaded method value thenReturn with alternatives error, I want to share my solution as well.
Instead of
when(field.getValue(isA(classOf[Record]))).thenReturn(value)
I use
doReturn(value).when(field).getValue(isA(classOf[Record]))
which resolves the disambiguity in my case.
The workaround is quite easy:
OngoingStubbing<T> thenReturn(T value);
OngoingStubbing<T> thenReturn(T value1, T valu2, T... values);
There is no "varargs must be non empty" feature.
I tried Steve's solution and got a huge compiler error including:
scala.tools.nsc.symtab.Types$TypeError: type mismatch;
found : scala.reflect.Manifest[Nothing]
required: scala.reflect.ClassManifest[B]
Note: Nothing <: B, but trait ClassManifest is invariant in type T.
You may wish to investigate a wildcard type such as `_ <: B`. (SLS 3.2.10)
I was able to make it work with something like:
thenReturn("something", Seq.empty[Object]: _*)
Related
Not really sure the standard terminology here, so I'll try to describe what I'm trying to do. In case you're curious, the app I'm actually trying to write is an asynchronous task queue similar to Resque or rq.
I have a type TaskDef[ArgsT <: AnyVal, ResultT <: AnyVal]. In case you're curious, TaskDef represents "how to execute an asynchronous task which takes argument type ArgsT and result type ResultT, or, the code behind a task".
I'm trying to define a type TaskInst[DefT <: TaskDef]. In case you're curious, TaskInst represents "a TaskDef and associated argument to run it with, or, an actual task instance being submitted to the queue". TaskInst has two members, definition: DefT and arguments whose type I cannot write in code.
In English, my desired constraint is: "For a given DefT, where DefT is some TaskDef[ArgsT, ResultT], TaskInst[DefT] should contain a DefT and an ArgsT". That is, the argument type of the task definition should match the type of the argument given to the task.
How do I express this in the Scala type system?
Alternatively, am I modeling my domain incorrectly and attempting to do something un-idiomatic? Would some alternative approach be more idiomatic?
Thanks in advance!
EDIT:
I think my historical self writing Java would probably have resorted to unchecked casts at this point. This is definitely feasible with some amount of unchecked casts and just leaving out the constraint between the type of the TaskInst's arguments vs the type of the embedded TaskDef's arguments. But, I do wonder whether this is something the compiler can enforce, and hopefully without too scary a syntax.
Define them as abstract types:
trait TaskDef {
type Arguments <: AnyVal
type Result <: AnyVal
}
Then use a type projection:
trait TaskInst[DefT <: TaskDef] {
def definition: DefT
def arguments: DefT#Arguments
}
Live Demo
An add-on to the answer that #rightfold gave:
If you are looking to use type parameters throughout, you will need to properly pass the type parameters through to the type constructors.
Excuse me, that's a bit ambiguous for me to say it that way, so let me use my current code as a concrete example.
trait TaskDef[ArgT_, ResT_] {
type ArgT = ArgT_
type ResT = ResT_
val name: String
def exec(arg: ArgT): String \/ ResT
}
class TaskInst[ArgT, ResT, DefT <: TaskDef[ArgT, ResT]] (
val id: UUID,
val defn: DefT,
val arg: ArgT
)
The main divergence of my current code from #rightfold's example is that TaskDef takes type parameters. Then, when TaskInst's declaration references TaskDef, it must provide appropriate types to the type constructor.
I initially made the mistake of passing in placeholders. That is, I was writing class TaskInst[DefT <: TaskDef[_, _]. Turns out, this doesn't mean what I thought it meant. (I don't know. Perhaps others might be inclined to follow the same line of thought. So, this is just a warning not to.) Don't do that, because then scalac will interpret the expected to mean a generated placeholder (which, as you might imagine, nothing matches), and then you get an obscure error message like the following.
[error] /Users/mingp/Code/scala-redis-queue/src/main/scala/io/mingp/srq/core/TaskInst.scala:8: type mismatch;
[error] found : TaskInst.this.arg.type (with underlying type _$1)
[error] required: _$1
[error] val arg: DefT#ArgT_
[error] ^
[error] one error found
Just posting this in hopes that future readers don't fall into the same hole I did.
EDIT:
As a further addendum, now that I've tried it out for a day, my impression is that this isn't actually a good data model for asynchronous tasks. You're better off combining, since stand-alone instances of TaskDef aren't really useful.
To clarify: I am NOT asking what I can use a Singleton design pattern for. The question is about largely undocumented trait provided in scala.
What is this trait for? The only concrete use case I could find so far was to limit a trait to objects only, as seen in this question: Restricting a trait to objects?
This question sheds some light on the issue Is scala.Singleton pure compiler fiction?, but clearly there was another use case as well!
Is there some obvious use that I can't think of, or is it just mainly compiler magicks?
I think the question is answered by Martin Odersky's comment on the mailing list thread linked to from the linked question:
The type Singleton is essentially an encoding trick for existentials
with values. I.e.
T forSome { val x: T }
is turned into
[x.type := X] T forSome { type X <: T with Singleton }
Singleton types are usually not used directly…
In other words, there is no intended use beyond guiding the typer phase of the compiler. The Scala Language Specification has this bit in §3.2.10, also §3.2.1 indicates that this trait might be used by the compiler to declare that a type is stable.
You can also see this with the following (Scala 2.11):
(new {}).isInstanceOf[Singleton]
<console>:54: warning: fruitless type test: a value of type AnyRef cannot also
be a Singleton
(new {}).isInstanceOf[Singleton]
^
res27: Boolean = true
So you cannot even use that trait in a meaningful test.
(This is not a definite answer, just my observation)
val mutator=HFactory.createMutator(keyspace,StringSerializer.get())
mutator.addInsertion("rahul", "user", HFactory.createColumn("birth_year", 1990,
StringSerializer.get(), LongSerializer.get()))//error in LongSerializer.get() as
mutator.execute()
I am using LongSerializer like above and i am getting the following error.
Description Resource Path Location Type
type mismatch; found : me.prettyprint.cassandra.serializers.LongSerializer
required: me.prettyprint.hector.api.Serializer[Any] Note: Long <: Any (and
me.prettyprint.cassandra.serializers.LongSerializer <:
me.prettyprint.cassandra.serializers.AbstractSerializer[Long]), but Java-defined trait
Serializer is invariant in type T. You may wish to investigate a wildcard type such as _
<: Any. (SLS 3.2.10) User.scala /winoria/app/models line 22 Scala Problem
Tell me the solution .
There are a couple of things happening here.
First, Java does not allow primitive types as generics, so Hector's LongSerializer is an AbstractSerializer[java.lang.Long]. However you are working in Scala, so you need an AbstractSerializer[scala.Long]. Depending on circumstances Scala's Long can either be a primitive long or java.lang.Long. The good news is Scala is smart enough to figure out what to use and when. What you need here is a little type coercion: LongSerializer.get().asInstanceOf[Serializer[Long]]
The other suspect is that you need me.prettyprint.hector.api.Serializer[Any]. It looks like whatever you are calling your method on is lacking proper type declarations. A sample of surrounding code would help diagnose this further.
Edit:
Thanks for posting the surrounding code. It looks like you have a type disagreement. createColumn[N, V] is inferred as createColumn[String, Int], because the 1990 argument you have provided is an Int. This gets converted to java.lang.Int, which is a class and does not have type conversions like primitives do. This is why you get the error "int cannot be cast to long".
val mutator = HFactory.createMutator(keyspace, StringSerializer.get)
mutator.addInsertion(
"rahul", "user",
HFactory.createColumn( // Either do: HFactory.createColumn[String, Long]
"birth_year", 1990L, // Or make sure the type is inferred as Long
StringSerializer.get,
// Coerce serializer to scala.Long
LongSerializer.get.asInstanceOf[Serializer[Long]]))
mutator.execute()
First of all, I know that manifests are deprecated and it is better to use TypeTag, but for now, it is not an option for me, so please consider my problem:
How to check whether type represented by a manifest is a subtype of the type represented by manifest[Numberic[_]]?
Actually, I have a function that receives a manifest and I want to check whether it is numeric or not.
def isNumeric(m: Manifest[T]) : Boolean = m <:< manifest[Numeric[_]]
But, it does not work, e.g. for an input of manifest[Double].
Any idea, how to make it work?
Numeric is a type class and it has nothing with subtyping and Manifest (or TypeTag).
Double is not a Numeric. T : Numeric in type parameter means there is implicit value of type Numeric[T] in scope. You can't check it via reflection.
Maybe you could search for implicit in macros, but I'm not sure and I don't think it's what you are looking for.
So the answer is: You just can't.
It isn't possible even in theory: there is no information about implicit values in runtime and there is no instance of Manifest[T] in compile time.
Code seems trivial but I'm not understanding one thing in the return value:
trait JdbcTemplate {
def query(psc: PreparedStatementCreator,
rowMapper: RowMapper): List[_]
}
What exactly does List[_] mean here? Wouldn't using List[Any] imply the same thing? Where can I read on the differences?
Any is a specific, known (though utterly all-inclusive) type. The use of the underscore as type parameter is a shorthand for a more cumbersome and more general syntax for what is called an "existential type." Existential types are non-specific: They say there's at least one type that could go here. They are the dual of universal quantification that is the interpretation of the more commonly used unbounded type parameters. E.g., def method[T](t: T) .... In this construct, T may be bound to any type whatsoever though at each place where that type is instantiated (every occurrence of a call to that method), it is bound to a specific type.
Given that _ means you don't care about the type and Any is supertype of everything, both are the same.