newlogic
newlogic

Reputation: 827

Scala: Sending/processing typed messages to/with Actors

I'm trying to create a Scala Actor that has an Option pipeline. I want to be able to send Option messages to this actor, which will then go on to invoke the option pipeline and do something with the result. If something like this exists already do you know where I can find it?

Please find my code below along with the strange compile error i'm getting:

"The SBT builder crashed while compiling your project. This is a bug in the Scala compiler or SBT. Check the Erorr Log for details. The error message is: null"

MonadChainActor.scala

import scala.actors.Actor

class MonadChainActor[T](monadChain: Option[T]=>Option[T]) extends Actor {

  case class OptionMessage(o:Option[T])

  def act() {
    while(true){
      receive {
        case OptionMessage(o) => println(monadChain(o).get)
      }
    }
  }

}

Main.scala

def monadIntChain(a:Option[Int]):Option[Int] = 
  a.map(x => x+1).map(x => x+1).map(x => x+1)

object Main {
  def main(args: Array[String]): Unit = {
    var a = new MonadChainActor(monadIntChain)
    a ! a.OptionMessage(Some(1))  
  }
}

Upvotes: 2

Views: 193

Answers (1)

Jordão
Jordão

Reputation: 56457

Looks like you found a bug in the scala compiler. I noticed that if you don't use the path-dependent type OptionMessage, it works (I've also added a Stop message):

import scala.actors.Actor

class MonadChainActor[T](monadChain: Option[T]=>Option[T]) extends Actor {
  case object Stop
  def act() {
    while (true) {
      receive {
        case o: Option[T] => println(monadChain(o).get)
        case Stop => exit()
      }
    }
  }
}

object Main {
  def monadIntChain(a:Option[Int]):Option[Int] = 
    a.map(x => x+1).map(x => x+1).map(x => x+1)
  def main(args: Array[String]): Unit = {
    var a = new MonadChainActor(monadIntChain)
    a.start
    a ! Some(3)  
    a ! a.Stop
  }
}

Or you can declare it outside the actor (I declared Stop outside just to be consistent):

import scala.actors.Actor

case class OptionMessage[T](o:Option[T])
case object Stop

class MonadChainActor[T](monadChain: Option[T]=>Option[T]) extends Actor {
  def act() {
    while (true) {
      receive {
        case om : OptionMessage[T] => println(monadChain(om.o).get)
        case Stop => exit()
      }
    }
  }
}

object Main {
  def monadIntChain(a:Option[Int]):Option[Int] = 
    a.map(x => x+1).map(x => x+1).map(x => x+1)
  def main(args: Array[String]): Unit = {
    var a = new MonadChainActor(monadIntChain)
    a.start
    a ! OptionMessage(Some(3))  
    a ! Stop
  }
}

Upvotes: 1

Related Questions