I will not paste the code here, I simply have this:
https://github.com/akka/akka/blob/master/akka-samples/akka-sample-hello/src/main/scala/sample/hello/Main.scala
And I wonder why Eclipse gives error on
def receive
saying:
type mismatch; found : Any => Unit required: akka.actor.Actor.Receive
(which expands to) PartialFunction[Any,Unit]
I suppose it's something about the fact that there are some "case" statements inside a block without a "match" in front.
How can I remove the error, or how can I make eclipse runnning well with Akka?
Related
A common pattern I have in my code base is to define methods with Try[Unit] to indicate the method is doing something (like writing a transaction long to a SaaS REST endpoint) where there is no interesting return result and I want to capture any and emit any errors encountered to stdout. I have read on another StackOverflow thread this is entirely acceptable (also see 2nd comment on the question).
I am specifically and explicitly avoiding actually throwing and catching an exception which is an extraordinarily expensive activity on most JVM implementations. This means any answer which uses the Try() idiom won't help resolve my issue.
I have the following code (vastly simplified from my real life scenario):
def someMethod(transactionToLog: String): Try[Unit] = {
val result =
for {
_ <- callToSomeMethodReturningATryInstance
} yield Unit
result match {
case Success(_)
//Unit
case Failure(e) ->
println(s"oopsie - ${e.getMessage}")
}
result
}
Sometimes this code compiles just fine. Sometimes it doesn't. When it doesn't, it gives me the following compilation error:
Error:(row, col) type mismatch;
found : scala.util.Try[Unit.type]
required: scala.util.Try[Unit]
result
^
Sometimes the IntelliJ syntax highlighter shows the code as fine. Other times it shows an error (roughly the same as the one above). And sometimes I get the compiler error but not a highligher error. And other times it compiles fine and I get only a highlighter error. And thus far, I am having a difficult time finding a perfect "example" to capture the compiler error.
I attempted to "cure" the issue by adding .asInstanceOf[Unit] to the result of the for comprehension. That got it past the compiler. However, now I am getting a runtime exception of java.lang.ClassCastException: scala.Unit$ cannot be cast to scala.runtime.BoxedUnit. Naturally, this is infinitely worse than the original compilation error.
So, two questions:
Assuming Try[Unit] isn't valid, what is the Scala idiomatic (or even just preferred) way to specify a Try which returns no useful Success result?
Assuming Try[Unit] is valid, how do I get past the compilation error (described above)?
SIDENOTE:
I must have hit this problem a year ago and didn't remember the details. I created the solution below which I have all over my code bases. However, recently I started using Future[Unit] in a number of places. And when I first tried Try[Unit], it appeared to work. However, the number of times it is now causing both compilation and IDE highlighting issues has grown quite a bit. So, I want to make a final decision about how to proceed which is consistent with whatever exists (or is even emerging) and is Scala idiomatic.
package org.scalaolio.util
/** This package object serves to ease Scala interactions with mutating
* methods.
*/
package object Try_ {
/** Placeholder type for when a mutator method does not intend to
* return anything with a Success, but needs to be able to return a
* Failure with an unthrown Exception.
*/
sealed case class CompletedNoException private[Try_] ()
/** Placeholder instance for when a mutator method needs to indicate
* success via Success(completedNoExceptionSingleton)
*/
val completedNoExceptionSingleton = new CompletedNoException()
}
Replace yield Unit with yield ().
Unit is a type - () is a value (and the only possible value) of type Unit.
That is why for { _ <- expr } yield Unit results in a Try[Unit.type], just as yield String would result in a Try[String.type].
I have a actor message of the following type:
case class RetrieveEntities[A](func:(Vector[A]) => Vector[A])
I then would like to handle the message in the following way:
def receive = {
case RetrieveEntities(parameters, func) =>
context.become(retrieveEntities(func))
def retrieveEntities(func:(Vector[T]) => Vector[T])(implicit mf: Manifest[T]){
case _ => ...
}
And I instantiate the actor in the following way:
TestActorRef(new RetrieveEntitiesService[Picture])
The problem is I receive the following compiler error:
type mismatch;
[error] found : Vector[Any] => Vector[Any]
[error] required: Vector[T] => Vector[T]
[error] context.become(retrieveEntities(func))
Which I suppose means I lost the type information but I am unsure why and how to prevent it.
Your example code is a bit to short to give you a solution, but from what you show it seems like what you are trying to do is not possible.
This is why
In Scala (and Java) the type parameters are erased, which means they disappear after compilation, so during runtime they are no longer available. This means that your pattern match on RetrieveEntities(parameters, func) is really a match where A can be anything. You then go on and call a method that is typed with T and there is no way for the compiler to know what you mean with that.
Manifest (which is deprecated), TypeTag and ClassTag are a mechanism that tells the compiler to create an object that provides type information for those after compilation but you have to "save" that information.
To be able to know what A you typed your RetrieveEntitiesService with you would need to take an implicit ClassTag to the constructor to base any logic on it (since when calling the constructor is the time that you know what A is):
import scala.reflect.ClassTag
case class RetrieveEntities[A](func:(Vector[A]) => Vector[A])(implicit val tag: ClassTag[A])
You could then call runtimeClass on the tag to get the type of A:
scala> val retrieve = RetrieveEntities[String](identity)
scala> retrieve.tag.runtimeClass
res2: Class[_] = class java.lang.String
Note that this still would not let you type a method call with since we are now in runtime, but it would let you use that instance of Class to compare with the runtimeClass of E of the actor and then do a safe cast to RetrieveEntities[E] if you like. (and also regular runtime conditional flows, reflection etc.).
Two important notes before you start doing that
I would not advice you to go down that path until you are more confident with the type system and really really know that there is no other reasonable design that solves your problem. Again I can not help you towards such a solution with the sparse example code given. (Maybe your actor does not really need to know about the type of A for example, or there is a limited set of E:s that you might match on with concrete types)
As an additional warning, type and class tags are not thread safe in Scala 2.10, and might not be safe in 2.11 either, so mixing them with actors might be a bad idea. (http://docs.scala-lang.org/overviews/reflection/thread-safety.html)
johanandren's answer was certainly helpful, but at the end I found a way that it could compile and it is working for now.
I needed to give the compiler a more precise type annotation to make it work:
case RetrieveEntities(parameters, func:(Vector[T]) => Vector[T])
I still will continue to use Manifest instead of the new Reflection API (TypeTag and ClassTag) mainly because the library I am using (json4s) uses internally also the Manifest implementation, and I assume it will lead to less problems this way.
I have a beginners Scala question. I have a class, Sample which extends the trait SampleAPI. Now I'm trying to build a sequence of Sample instances using seq. I will look something like this:
var samples: Seq[SampleAPI] = Seq()
for(...) {
samples :+= new Sample(...))
}
This gives me the following compiler error: "type mismatch; found : Seq[java.lang.Object] required: Seq[se.uu.medsci.queue.setup.SampleAPI]"
So I tried:
samples :+= (new Sample(sampleName, this, illuminaXMLReportReader)).asInstanceOf[SampleAPI]
Which instead throws a runtime exception, saying that Sample cannot be bast to SampleAPI. I guess that this comes down to a problem in my understanding of the use of traits in Scala. Any help in figuring this out would be much appreciated.
Is the compiler error coming up on this line?
samples :+= new Sample(...))
If so, I think the problem is that your Sample class doesn't actually extend SampleAPI.
What's happening has to do with the contravariant type parameter of the List type in Scala. If you start with a List[SampleAPI], then add a Sample to that list, it needs to find the least-upper-bound on the types included in the list to use as the new type parameter. If Sample is a SampleAPI, then the least-upper-bound is just SampleAPI and you get a List[SampleAPI] as the result of the :+= operation. However, if Sample is not a SampleAPI then the least-upper-bound on the two types is just Object, hence your compiler error saying that it was expecting a Seq[SampleAPI] but found a Seq[Object].
I'm trying to assign groups to TestNG classes and methods in a Scala environment (in Eclipse)
#Test(groups="register")
class RegisterTest {
...
but am encountering the following error:
Multiple markers at this line
- type mismatch; found : java.lang.String("register") required:
Array[java.lang.String]
- annotation argument needs to be a constant; found: "register"{<error>}
I've tried applying groups to individual Scala methods but still encounter the same error.
Any suggestions on how to get around this?
The#Testannotation works as long as it doesn't specify any parameters (same error if dependsOnMethodsparameter is specified).
#DataProviderannotation also works.
The ScalaDoc gives the following example:
#Test(groups = Array("com.mycompany.groups.SlowTest"))
def funTest() {
sb.append("fun!")
assert(sb.toString === "ScalaTest is fun!")
assert(lb.isEmpty)
}
That seems to match the error you get.
9 times out of 10, simply using Map and Set behave like I expect they would, but occasionally I am unexpectedly hit with
error: type mismatch;
[INFO] found : scala.collection.Set[String]
[INFO] required: Set[String]
As an example, from the REPL:
scala> case class Calculator[+T](name: String, parameters: Set[String])
defined class Calculator
scala> val binding=Map.empty[String, String]
binding: scala.collection.immutable.Map[String,String] = Map()
scala> Calculator("Hello",binding.keySet)
<console>:9: error: type mismatch;
found : scala.collection.Set[String]
required: Set[String]
Calculator("Hello",binding.keySet)
^
I think I understand the error, that is, the function call on the aliased types return the actual types.
And so it seems to me the solution is to import the un-aliased types. Upon which every other file in my project will now generate type mismatch errors, so I will have to import it in each file. Which leads to the question I ask in the title -- what was the purpose of the alias in Predef, if eventually I need to import the actual package anyway?
Is my understanding flawed, or is my use case not the typical one, or both?
You have misdiagnosed the problem. It isn't that it doesn't recognize the type alias is the same type as what it is aliasing. It's that the type alias is scala.collection.immutable.Set and that is not the same as scala.collection.Set.
Edit: by the way, I thought I'd fixed this, as evinced by the comment in the type diagnostics:
... Also, if the
* type error is because of a conflict between two identically named
* classes and one is in package scala, fully qualify the name so one
* need not deduce why "java.util.Iterator" and "Iterator" don't match.
Apparently needs more work.
Edit 7/17/2010: OK, it took me a shockingly long time, but now at least it says something hard to misunderstand.
files/neg/type-diagnostics.scala:4: error: type mismatch;
found : scala.collection.Set[String]
required: scala.collection.immutable.Set[String]
def f = Calculator("Hello",binding.keySet)
^
The real problem is that scala.collection.immutable.Map#keySet returns a scala.collection.Set (a read-only Set) instead of a scala.collection.immutable.Set (an immutable Set). I'll leave it for someone else to explain why that is...
Edit
Someone asks for an explanation for the return type of Map#keySet in this thread, but doesn't get an answer.