Come parte del mio viaggio Haskell, sto implementando un raytracer e ho bisogno di essere in grado di disegnare sequenze di numeri casuali in diversi punti del codice. In genere mi piacerebbe essere in grado di dire 64 campioni per ogni pixel e i pixel sono calcolati in parallelo.Sequenza di numeri casuali di Haskell e State Monad, cosa sto facendo male?
Stavo osservando la monade di stato per ottenere ciò ed ero guidato da questa risposta Sampling sequences of random numbers in Haskell ma il codice che ho scritto non termina e il suo consumo di memoria esplode.
Qui è la parte astratta del codice: mi saltellava per essere in grado di chiamare sampleUniform
più volte nel codice per ottenere nuovi elenchi di numeri casuali, ma se lo faccio runhaskell test.hs
, si emette il primo carattere della LIS [
e poi è bloccato in un ciclo apparentemente infinito.
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
Vedi anche [Perché la funzione di sequenza Haskell non può essere pigri o perché funzioni ricorsive monadici non può essere pigro] (http://stackoverflow.com/q/31892418/1333025) .. –