W ramach mojej podróży Haskell, wdrażam raytracer i muszę mieć możliwość rysowania sekwencji liczb losowych w kilku miejscach kodu. Zazwyczaj chciałbym móc powiedzieć, że 64 próbki dla każdego piksela i pikseli są obliczane równolegle.Losowa sekwencja numerów un Haskell i State Monad, co robię źle?
Patrzyłem na monadę państwową, aby to osiągnąć i kierowałem się tą odpowiedzią Sampling sequences of random numbers in Haskell, ale napisany przeze mnie kod nie kończy się, a zużycie pamięci eksploduje.
Oto wydobywane część kodu: I był cudny, aby móc nazwać sampleUniform
kilka razy w kodzie, aby uzyskać nowe listy liczb losowych, ale jeśli to zrobię runhaskell test.hs
, wyprowadza pierwszy znak Lis [
a następnie utknęła w pozornie nieskończonej pętli.
module Main (main
, computeArray) where
import Control.Monad
import Control.Monad.State (State, evalState, get, put)
import System.Random (StdGen, mkStdGen, random)
import Control.Applicative ((<$>))
type Rnd a = State StdGen a
runRandom :: Rnd a -> Int -> a
runRandom action seed = evalState action $ mkStdGen seed
rand :: Rnd Double
rand = do
gen <- get
let (r, gen') = random gen
put gen'
return r
{- Uniform distributions -}
uniform01 :: Rnd [Double]
uniform01 = mapM (\_ -> rand) $ repeat()
{- Get n samples uniformly distributed between 0 and 1 -}
sampleUniform :: Int -> Rnd [Double]
sampleUniform n = liftM (take n) uniform01
computeArray :: Rnd [Bool]
computeArray = do
samples1 <- sampleUniform 10
samples2 <- sampleUniform 10
let dat = zip samples1 samples2
return $ uncurry (<) <$> dat
main :: IO()
main = do
let seed = 48
let res = runRandom computeArray seed
putStrLn $ show res
Zobacz również [Dlaczego funkcja sekwencja Haskell nie może być leniwy albo dlaczego rekurencyjne funkcje monadycznego nie może być leniwy] (http://stackoverflow.com/q/31892418/1333025) .. –