|
Das letzte ist die Hauptfunktion, welche man von hinten nach vorne lesen kann: Erzeuge mit Hilfe eines Zufallsgenerators eine unendliche Liste von (-1,1)-gleichverteilten Zufallszahlen (randomRs), wandele sie in eine Liste von Paaren um (bundlePairs), bestimme zu jedem Punkt den quadrierten Abstand vom Kreismittelpunkt (map (\p -> (p, norm2sqr p))) und beachte nur die Zahlen, die im Kreis liegen (filter ((<=1) . snd)), wandele die Punkte in normalverteilte Größen um (normalDist) und reihe die Zahlenpaare wieder in eine Liste von Zahlen ein (resolvePairs).
Wir arbeiten die ganze Zeit formal mit unendlichen Listen, aber die verzögerte Auswertung kümmert sich nur um die Werte, die wirklich gebraucht werden, und das sind immer nur endlich viele. Wir müssen im wesentlichen nur aufschreiben, was wir machen wollen, aber wir können viele Details weglassen, darüber wie wir es machen wollen. Wenn wir beispielsweise den ersten Wert von randomGaussians abfragen, werden automatisch zwei Zufallszahlen generiert, diese zu einem Paar zusammengefasst, das Zahlenpaar wie gewünscht verarbeitet und nur die erste Zahl wird ausgegeben. Wenn wir die zweite Zahl abfragen, wird nur noch (p*y) in normalDist berechnet.
Der Box-Müller-Generator ist bereits in der HaskellDSP?-Bibliothek verewigt.
http://haskelldsp.sourceforge.net/doc/Numeric.Random.Distribution.Normal.html#normal_bm