Ich arbeite mit den Paketen System.Random.Mersenne.Pure64 und Control.Monad.Mersenne.Random von Don Stewart, die normalerweise unglaublich schnell sind und helfen sollen, häufige Fehler zu vermeiden , wie die Verwendung nicht strikter Zustands-Monaden.
Trotzdem habe ich es geschafft, Code zu schreiben, der zu einem Stack-Überlauf für mäßig große Vektoren führt.
%Vor% Ich vermute, dass dies auf Faulheit in Vectors replicateM
Implementierung zurückzuführen ist, obwohl es schwer zu sehen ist, da es mit streams
implementiert wurde.
Wie kann ich Code schreiben, der konstanten Stapelraum zum Abtasten großer Vektoren verwendet?
Nichts war offensichtlich offensichtlich falsch mit Monad-Mersenne-Random (habe nicht auf Kern Iota geschaut), aber es ist bemerkenswert, dass alles funktioniert, wenn die State Monade verwendet wird:
%Vor%Mit einem Ergebnis von:
%Vor%BEARBEITEN:
Betrachtet man die beiden Monaden-Definitionen ( StateT
und Rand
) so scheint der einzige wirkliche Unterschied in der Strenge des Tupels zu liegen. Also habe ich versucht mit Control.Monad.State.Strict
und ah-ha! Der Stapelüberlauf ist zurückgekehrt. Ich vermute also, dass in Vectors replicateM
Code vergraben etwas ist, das dem foldr
ähnelt, das in replicateM
von base
verwendet wird. Dies würde erklären, warum Sie nicht möchten, dass die Sequenz streng ist.
Tags und Links haskell monads lazy-evaluation stack-overflow