2

I want to be able to define such a nice receive function in scala

sealed trait DoParent
case object DoThis extends DoParent
case object DoThat extends DoParent

object MyApp extends App {

  val receive = {
    case DoThis => println("dothis")
    case DoThat => println("dothat")
  }


  receive(DoThis)

}

but it generates

missing parameter type for expanded function
The argument types of an anonymous function must be fully known. (SLS 8.5)
Expected type was: ?
  val receive = {
                ^

I now I understand it asks me to add the type but i want the receive to look as neat and clean (define only the cases inside as shown without the types) as actors receive looks like, what am i missing?

thanks

3 Answers 3

1

I doubt there is a way around the type specification. The way actors do it is they declare receive in parent trait such as:

trait WithReceive {
    def receive:PartialFunction[DoParent, Unit] //for some reason this needs to be a def
}

And then have your object inherit from that trait:

object MyApp extends App with WithReceive {
    def receive = { //this needs to be a def too
        case DoThis => ???
        case DoThat => ???
    }
}

For some reason it needs to be a def, using val results in the same error you got.

Sign up to request clarification or add additional context in comments.

1 Comment

There was just a long ML thread about why it must be a def: groups.google.com/d/msg/scala-language/1FMHSbGkIMw/ZMGfcugZFCIJ with issue issues.scala-lang.org/browse/SI-2742 so maybe soon the val's RHS will also be typechecked with the type in the trait.
1

If I understood you correctly:

val receive: DoParent => Any = {
  case DoThis => println("dothis")
  case DoThat => println("dothat")
}

receive(DoThis)
receive(DoThat)

Output:

dothis
dothat

Comments

1

The problem is that while you "know" that you want the argument to be of type DoParent, the Scala compiler doesn't. You could want it to accept for example Any... That's why you must annotate your function value with a type:

val receive: DoParent => Unit = {
  case DoThis => println("dothis")
  case DoThat => println("dothat")
}

You could also use a method instead of a function value:

def receive(x: DoParent) = x match {
  case DoThis => println("dothis")
  case DoThat => println("dothat")
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.