Dostałem aplet java do łączenia się i komunikowania za pomocą zastrzeżonego autobusu przy użyciu stylu opartego na oddzwanianiu. Obecnie wdrażam aplikację proof-of-concept w scala i próbuję ustalić, w jaki sposób mogę stworzyć nieco bardziej idiomatyczny interfejs scala.Czy mogę przekształcić ten asynchroniczny interfejs sieciowy Java w monadyczną reprezentację (lub coś innego idiomatycznego)?
Typowym (uproszczony) aplikacja może wyglądać to w 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();
w Scala mogę oczywiście zdefiniować niejawna konwersja z (T => Jednostki) w jego IListener, co z pewnością sprawia, że rzeczy, bit łatwiejsze do odczytania:
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
})
})
Patrząc na to przypomniało mi obie obietnice scalaz i f # asynchroniczne przepływy pracy.
Moje pytanie jest takie:
mogę przekonwertować to do albo do zrozumienia lub coś podobnie idiomatyczne (czuję się jak to powinno map do aktorów dość dobrze też)
Idealnie chciałabym zobaczyć coś takiego:
for(
d <- con.waitForData(DataType.getClass);
val _ = doSomethingWith(d);
o <- con.waitForData(OtherType.getClass)
//etc
)
Scalaz dostarcza 'Monad [Responder]', więc legalnie masz instancję monady, jeśli robisz to, co sugeruje Ben Lings. Ponadto "Odpowiadający" jest rodzajem "uniwersalnej monady", ponieważ można zaimplementować dowolną inną monadę. – Apocalisp
Odpowiadający dał mi dokładnie prawidłowe zachowanie, chociaż z jakiegoś powodu musiałem użyć 'def onEvent (t: T) = k (t)' zamiast tylko '= k' – AlecZorab