J'ai reçu une API Java pour la connexion et la communication via un bus propriétaire en utilisant un style de rappel. Je suis en train de mettre en place une application de preuve de concept en scala, et j'essaye de trouver comment je pourrais produire une interface de scala légèrement plus idiomatique.Puis-je transformer cette API de réseau java asynchrone en une représentation monadique (ou quelque chose d'autre idiomatique)?
Une application typique (simplifiée) pourrait ressembler à ceci en 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();
En scala je peux définir évidemment une conversion implicite de (T => Unité) dans un IListener, ce qui rend certainement choses peu plus simple à lire:
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
})
})
en regardant cela me rappelle des deux promesses scalaz et f workflows # async.
Ma question est la suivante:
Puis-je convertir en soit une pour la compréhension ou quelque chose de la même idiomatiques (je me sens comme cela devrait cartographier les acteurs assez bien aussi)
Idéalement, je voudrais voir quelque chose comme:
for(
d <- con.waitForData(DataType.getClass);
val _ = doSomethingWith(d);
o <- con.waitForData(OtherType.getClass)
//etc
)
Scalaz fournit 'Monad [Responder]', donc vous avez légitimement une instance monad si vous faites ce que Ben Lings suggère ici. En outre, 'Responder' est une sorte de" monade universelle "en ce sens que vous pouvez implémenter n'importe quelle autre monade. – Apocalisp
Répondeur m'a donné exactement le bon comportement, bien que pour une raison quelconque, j'ai dû utiliser 'def onEvent (t: T) = k (t)' au lieu de simplement '= k' – AlecZorab