2011-05-09 7 views
3

Je joue actuellement avec des contrats à terme non bloquants de Scalaz. Promesses. Je me bats pour faire la queue récursif de fonction suivante:Promesses de rançon-récursivité et de scala

@tailrec 
private def repeat(res: Promise[I]):Promise[I] = 
    res map p flatMap { 
    (b:Boolean) => 
     if(b) repeat(res flatMap f) else res 
    } 

p est un prédicat de type I=>Boolean et f est une fonction concurrente avec de type I=>Promise[I].

La méthode se compile sans l'annotation.

Des indices? Merci

Répondre

4

Votre méthode n'est pas récursive du tout. res est un calcul potentiellement en cours d'exécution dans un autre thread. res map p flatMap f retournera immédiatement une promesse en ce qui concerne votre méthode. La récurrence à repeat se produira dans un processus différent.

En termes légèrement plus laconiques, Promise est une monade de continuation, et les appels flatMap sont automatiquement traduits en style continuation-passing pour vous.

1

Bien que cela semble récursif queue parce que l'appel n'apparaît qu'une seule fois dans le code, vous avez plus d'un appel récursif - un pour chaque élément à l'intérieur de votre collection. Au moins, c'est ce que le compilateur voit. (Supposons qu'il s'agisse d'un flatMap sur une collection, je n'ai aucune idée de ce que renvoie p)

Vous passez la récursivité à quelque chose comme une fonction anonyme. Personne ne sait combien de fois il sera exécuté.

+0

Merci pour cette réponse. Mais avez-vous une idée de comment je peux résoudre cela sans bloquer? – paradigmatic

+2

Je suis désolé mais je ne suis pas familier avec scalaz. J'ai juste essayé de savoir ce que l'appel 'p' dans votre code est et a échoué. Pouvez-vous penser à une version procédurale de votre code qui utilise une boucle while? Si ce n'est pas possible, il ne peut pas y avoir de tco. – ziggystar

+1

"un pour chaque élément de votre collection, c'est du moins ce que voit le compilateur." est incorrect, IMHO: 'Promise' n'est pas une collection et le compilateur ne voit qu'un appel (pas en position de queue). Cependant, le deuxième paragraphe est à la fois correct et suffisant pour expliquer pourquoi ce n'est pas récursif de la queue. –

Questions connexes