Reputation: 37633
I'm working with akka actors. All actors should implemented the receive
method, which has a signature of PartialFunction[Any, Unit]
. I want to define a stricter function to use for the matching with signature like PartialFunction[Action, Unit]
. However, this doesn't compile:
class PlayerActor extends Actor with {
override def receive: Receive = rec
def rec: PartialFunction[Action, Unit] = {
case Jump() =>
}
}
I want to do this so the compiler will warn me if I forget a case.
Receive
is defined as type Receive = PartialFunction[Any, Unit]
I ended up doing it manually like:
override def receive = {
case a: Action => rec(a)
}
It can also be done by casting:
override def receive = rec.asInstanceOf[PartialFunction[Any, Unit]]
Or via an implicit conversion:
implicit def toAnyPartial[T](f: PartialFunction[T, Unit]): PartialFunction[Any, Unit] =
f.asInstanceOf[PartialFunction[Any, Unit]]
Upvotes: 1
Views: 234
Reputation: 38045
If all you want is to create PartialFunction[Any, Unit]
using implementation of type PartialFunction[T, Unit]
you could try this:
implicit def toPfAny[T](pf: PartialFunction[T, Unit]): PartialFunction[Any, Unit] = {
object PF { def unapply(a: T): Option[Unit] = pf.lift(a) }
{ case PF(_) => () }
}
Usage:
scala> def impl: PartialFunction[String, Unit] = { case s => println(s) }
impl: PartialFunction[String,Unit]
scala> def receive: PartialFunction[Any, Unit] = impl
receive: PartialFunction[Any,Unit]
Upvotes: 1
Reputation: 8139
You could try this
def rec: Receive = { case a: Action => a match {
case Jump() =>
}}
Upvotes: 2
Reputation: 13221
PartialFunction
is contravariant on its first type parameter. I shall not dig into explanation what this means (there are books, blog posts, SO questions & answers), but will give you very trivial example instead.
You are allowed to pass Any
to receive
. If it would be possible to assign rec
to receive
, it would mean you may pass Any
to rec
, thus bypassing rec
's type. Compiler prohibits it.
Upvotes: 1