Ich möchte zufällige Berechnungen in Haskell mit einem Timeout unter Verwendung der Control.Monad.Random
-Bibliothek auswerten. Die folgenden funktioniert gut:Haskell - Timing-Out-Berechnungen in der Rand-Monade
ghci> import System.Timeout
ghci> import Control.Monad.Random
ghci> timeout 1000 . evalRandIO $ getRandomR (True, False)
Just True
Doch dieser Ansatz scheint nicht zu funktionieren, wenn wir eine Berechnung des Typs Rand StdGen a
haben, die nie (das heißt auswertet nach unten) endet. Zum Beispiel:
ghci> let f = f :: Rand StdGen Bool
ghci> timeout 1000 $ evalRandIO f
Just
Hier GHCI druckt "Just" und dann auf unbestimmte Zeit hängt, versucht f
zu bewerten. Kann jemand, der mehr über die Haskell-Laufzeit weiß als ich, erklären, warum dies geschieht und wie man es umgehen kann? Meine Vermutung ist, dass der Ausdruck evalRandIO f
zu WHNF ausgewertet wird und so timeout 10
denkt, dass die Berechnung beendet wird, aber ich habe wirklich keine Ahnung.
Vielen Dank! Ich muss deutlich über seq/deepseq und die Haskell-Laufzeit lernen. – user3873438
@ user3873438 Um fair zu sein, musste ich eine GHCi-Sitzung laden, um es selbst herauszufinden. Faulheit verursacht einige interessante Probleme, aber die meiste Zeit müssen Sie nicht einmal darüber nachdenken. Wenn Sie Probleme haben, die in einer bestimmten Reihenfolge passieren müssen, müssen Sie sich erst einmal Gedanken über die Striktheit machen. In diesem Fall sollte evalRandIO f vor dem Ende von timeout 1000 auftreten. Bei einer solchen Beziehung ist es wichtig, explizit auf Strenge hinzuweisen, was 'deepseq' und' $! 'Tun. – bheklilr
Sie müssen auch über Faulheit für Raumlecks und Parallelität sorgen. – PyRulez