Мне дана java api для подключения и связи через проприетарную шину с использованием стиля, основанного на обратном вызове. В настоящее время я внедряю приложение-доказательство в scala, и я пытаюсь понять, как я могу создать немного более идиоматический интерфейс scala.Могу ли я преобразовать этот асинхронный API-интерфейс Java в монадическое представление (или что-то еще идиоматическое)?
Типичное (упрощенно) приложение может выглядеть следующим образом в 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();
В Скале я, очевидно, могу определить неявное преобразование из (T => Unit) в качестве 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
})
})
Глядя на это напомнило мне как scalaz обещаний и F # асинхронными рабочие процессы.
Мой вопрос заключается в следующем:
Можно ли преобразовать это в либо для понимания или что-то подобного идиоматического (я чувствую, как это следует сопоставить с актерами достаточно хорошо тоже)
В идеале я хотел бы видеть что-то вроде:
for(
d <- con.waitForData(DataType.getClass);
val _ = doSomethingWith(d);
o <- con.waitForData(OtherType.getClass)
//etc
)
Scalaz предоставляет «Monad [Responder]», поэтому у вас законно есть экземпляр монады, если вы делаете то, что предлагает здесь Блин Лингс. Кроме того, «Responder» - своего рода «универсальная монада», в которой вы можете реализовать любую другую монаду в терминах этого. – Apocalisp
Ответчик дал мне точно правильное поведение, хотя по какой-то причине мне пришлось использовать 'def onEvent (t: T) = k (t)' вместо просто '= k' – AlecZorab