This question is certainly for stackoverflow.com
here is the sample
module Main where
import Control.Monad.Random
import Control.Exception
data Tdata = Tdata Int Int Integer String
randomTdata :: (Monad m, RandomGen g) => RandT g m Tdata
randomTdata = do
a <- getRandom
b <- getRandom
c <- getRandom
return $ Tdata a b c "random"
manyTdata :: IO [Tdata]
manyTdata = do
g <- newStdGen
evalRandT (sequence $ repeat randomTdata) g
main = do
a <- manyTdata
b <- evaluate $ take 1 a
return ()
after compilation this return
Stack space overflow: current size 8388608 bytes.
Use `+RTS -Ksize -RTS' to increase it
How can it happen ? Is MonadRandom not lazy or what else ? And how to define the cause of stack overflow in cases like that ?
The issue arises because you are building
IOinto yourmanyTdatafunction.The monad transformer ends up being of type
RandT g IO Tdata. Because each element ofyour infinite list can consist of
IOactions, the entirety of the infinite listreturned by
manyTdatamust be evaluated completely before the function can returnany results.
The simplest solution would be to use
Randinstead ofRandT, as using the tranformerisn’t really useful here, anyway; you could also change the base monad to something like
the
Identitymonad by changingmanyTdatatoWhich will terminate in a finite amount of time. The error concerning your stack size
is simply a result of recursively expanding your list of
IOactions. Your code says to sequence all of these actions, so they all have to be performed, it has nothing to do with laziness.Something else to think about, rather than using
randomTdata, considermaking
Tdataan instance of theRandomclass.