我已经给出了一个java api,用于连接并使用基于回调的风格通过专用总线进行通信。我目前正在scala中实现一个概念验证应用程序,我正在努力研究如何生成一个稍微更习惯的scala接口。我可以将这个异步java网络API转换为monadic表示形式吗?
典型(简体)应用程序可能看起来在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();
在Scala中我能明显从(T =>单元)定义的隐式转换成IListener,这无疑使事情比较简单:
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
})
})
看着这让我想起了斯卡拉承诺和f#异步工作流程。
我的问题是这样的:
我可以转换到这一点无论是对于理解或一些类似的习惯(我觉得这应该映射到角色相当不错太)
理想我想看看是这样的:
for(
d <- con.waitForData(DataType.getClass);
val _ = doSomethingWith(d);
o <- con.waitForData(OtherType.getClass)
//etc
)
Scalaz提供了'Monad [Responder]',所以如果你按照Ben Lings的建议,你可以合法地拥有一个monad实例。另外,'Responder'是一种“通用monad”,你可以在其中实现任何其他monad。 – Apocalisp 2010-04-25 18:22:09
响应者给了我正确的行为,虽然由于某种原因我不得不使用'def onEvent(t:T)= k(t)'而不是'= k' – AlecZorab 2010-04-26 09:47:45