Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pattern matching zero-argument functions in scala: mystified by warning

I'm playing with scala's distributed actors. Very nice.

I have a server which executes incoming function objects. For example, the client has

object Tasks {
  def foo = {Console.println("I am Foo")};
  def bar = {Console.println("I am Bar");}
}

// In client actor...
...
  server ! Tasks.foo _
...

And the server can pick these up and execute them with actor code like

react {
  case task:(()=>Unit) =>
    task()

This all works nicely (which is very very cool indeed) but I'm mystified by a warning message output by scalac for the server code:

warning: non variable type-argument Unit in type pattern is unchecked since it is eliminated by erasure
        case task:(()=>Unit) =>
                     ^

How can I clean this warning up ?

(I'm pretty unclear on the difference between the Unit type, and the ()=>Unit type of zero-argument functions. Just trying to match task:Unit in the react is warning-free, but actually doesn't match the incoming tasks.)

Using Scala 2.7.5 on Debian, with Sun's Java6.

like image 240
timday Avatar asked Oct 07 '09 23:10

timday


2 Answers

You are really matching this:

case task:Function0[Unit] => task()

Due to erasure, Unit is not visible at runtime. If you really don't care about the return type, you can do this in the react block:

case task:Function0[_] => task()
like image 89
Mitch Blevins Avatar answered Nov 09 '22 15:11

Mitch Blevins


This is complement to @Mitch Blevins's answer since his answer will get you through in this case.

See How do I get around type erasure on Scala? Or, why can’t I get the type parameter of my collections? You probably have to pass around a tuple of (Function0[T],Manifest[T]) to the actor. As you can see below, Scala is smart enough to deduce the type of T even if you just write matchFunction(foo _).

scala> def foo = {Console.println("I am Foo")}
foo: Unit

scala> import scala.reflect.Manifest
import scala.reflect.Manifest

scala> def matchFunction[T](f: Function0[T])(implicit m : Manifest[T]) {
     |   (m,f) match {
     |     case (om: Manifest[_],of: Function0[_]) =>
     |       if(om <:< m) {
     |         of.asInstanceOf[Function0[T]]()
     |       }
     |   }
     | }
matchFunction: [T](() => T)(implicit scala.reflect.Manifest[T])Unit

scala> matchFunction(foo _)
I am Foo
like image 40
Eugene Yokota Avatar answered Nov 09 '22 15:11

Eugene Yokota