Wie vermeidet man einen Stapelüberlauf bei der Verwendung von scalazs freier Monade?

8

Ich hatte vorher gedacht, dass ein Teil des Ziels der Implementierung war, genau dieses Problem zu vermeiden, also mache ich etwas offensichtlich dummes?

Hier ist ein Code:

%Vor%

Hinweis: Ich weiß, das ist albern :) In der Praxis hat meine Befehlsklasse viele Befehle, und ich habe einen Befehl, der diese selbe Schleife ausführt ... im Grunde, einen Zustand abfragen, wenn richtig abbrechen, wenn falsch, weiter warten .

Ich möchte den Stack-Überlauf vermeiden, der dies verursacht ... Ich dachte, das war schon Trampolin, aber ich denke, ich muss es manuell nochmal machen? Gibt es einen sauberen Weg, dies innerhalb der Denkweise der freien Monade zu tun?

Aktualisierung:

Wenn ich weiter darüber nachdenke, denke ich, dass das Problem nicht die Free Monade ist, sondern die Id.Id Monade, in die wir uns bei der Evaluation einklinken ... also versuchte ich etwas wie:

%Vor%

Aber das Problem dabei ist, dass es nur einen Schritt auswertet. Idealerweise möchte ich, dass runFC blockt, bis eine Bedingung erfüllt ist (oder in diesem Fall für immer eine Schleife durchlaufen wird, bis ich sie abbringe, aber ohne einen Stack-Überlauf)

    
A Question Asker 15.04.2015, 20:17
quelle

2 Antworten

6

Die Id Monade ist nicht trampolint. Sie landen in einer unendlichen gegenseitigen Rekursion zwischen der bind Methode für die Id Monade und der foldMap Methode für die freie Monade. Verwenden Sie Trampoline oder Task anstelle von Id .

    
Apocalisp 15.04.2015, 22:59
quelle
2

Seit @ Apocalisps Antwort wurde BindRec typeclass und foldMapRec Methode, die für die Stack-sichere Auswertung direkt zu Id (oder einer anderen" tail-rekursiven "Monade) verwendet werden kann. Weitere Informationen finden Sie Stack Safety for Free .

    
Tomas Mikula 13.12.2016 20:10
quelle

Tags und Links