Can I transform this asynchronous java network API into a monadic representation (or something else

Posted by AlecZorab on Stack Overflow See other posts from Stack Overflow or by AlecZorab
Published on 2010-04-24T16:04:03Z Indexed on 2010/04/24 19:43 UTC
Read the original article Hit count: 178

Filed under:
|

I've been given a java api for connecting to and communicating over a proprietary bus using a callback based style. I'm currently implementing a proof-of-concept application in scala, and I'm trying to work out how I might produce a slightly more idiomatic scala interface.

A typical (simplified) application might look something like this in Java:

    DataType type = new DataType();
    BusConnector con = new BusConnector();
    con.waitForData(type.getClass()).addListener(new IListener<DataType>() {
        public void onEvent(DataType t) {
            //some stuff happens in here, and then we need some more data
            con.waitForData(anotherType.getClass()).addListener(new IListener<anotherType>() {
                public void onEvent(anotherType t) {
                    //we do more stuff in here, and so on
                }
            });
        }
    });

    //now we've got the behaviours set up we call
    con.start();

In scala I can obviously define an implicit conversion from (T => Unit) into an IListener, which certainly makes things a bit simpler to read:

implicit def func2Ilistener[T](f: (T => Unit)) : IListener[T] = new IListener[T]{
  def onEvent(t:T) = f
}

val con = new BusConnector
con.waitForData(DataType.getClass).addListener( (d:DataType) => {
  //some stuff, then another wait for stuff
  con.waitForData(OtherType.getClass).addListener( (o:OtherType) => {
    //etc
  })
})

Looking at this reminded me of both scalaz promises and f# async workflows.

My question is this:

Can I convert this into either a for comprehension or something similarly idiomatic (I feel like this should map to actors reasonably well too)

Ideally I'd like to see something like:

for(
  d <- con.waitForData(DataType.getClass);
  val _ = doSomethingWith(d);
  o <- con.waitForData(OtherType.getClass)
  //etc
)

© Stack Overflow or respective owner

Related posts about scala

Related posts about scalaz