История изменений
Исправление qnikst, (текущая версия) :
а всё потому, что нужно разделять IO и чистые вычисления:
import Control.Applicative
import Data.List
import System.Random.Mersenne
normal :: [Double] -> [Double]
normal (u:v:xs) = (sqrt ((-2) * log u) * cos (2*pi*v)) : normal xs
sum_sum :: [Double] -> Double
sum_sum = sum
sum_foldl = foldl1 (+)
sum_foldl' = foldl1' (+)
sum_foldr = foldr1 (+)
main = do
print =<< (sum_foldl . take 1000000 . normal) <$> (randoms =<< getStdGen)
ключевой пункты:
1). в одно действие генерируем случайные числа нормальным генератором, это единственное (кроме вывода) IO, всё остальное чистое.
2). делаем нужное распределение normal, и вытаскиваем нужное кол-во элементов, из-за ленивости всё хорошо
3). обрабатываем левой сверткой, соотв foldl(') будут работать, sum и foldr - нет.
а в MWC-random есть разные распределения изкоробки.
Исходная версия qnikst, :
а всё потому, что нужно разделять IO и чистые вычисления:
import Control.Applicative
import Data.List
import System.Random.Mersenne
normal :: [Double] -> [Double]
normal (u:v:xs) = (sqrt ((-2) * log u) * cos (2*pi*v)) : normal xs
sum_sum :: [Double] -> Double
sum_sum = sum
sum_foldl = foldl1 (+)
sum_foldl' = foldl1' (+)
sum_foldr = foldr1 (+)
main = do
print =<< (sum_foldl . take 1000000 . normal) <$> (randoms =<< getStdGen)
ключевой пункты:
1). в одно действие генерируем случайные числа нормальным генератором, это единственное (кроме вывода) IO, всё остальное чистое.
2). делаем нужное распределение normal, и вытаскиваем нужное кол-во элементов, из-за ленивости всё хорошо
3). обрабатываем левой сверткой, соотв foldl(') будут работать, sum и foldr - нет.
а в MWC-random есть разные распределения изкоробки.