# [Haskell-cafe] infinite list of random elements

Lennart Augustsson lennart at augustsson.net
Mon Jul 30 18:04:18 EDT 2007

```Why this obsession with IO?  There should be no IO involved in this, except
for getting the initial generator.
Using IO just confuses what is going on.

-- Lennart

On 7/30/07, Cale Gibbard <cgibbard at gmail.com> wrote:
>
> > I'm trying to do something I thought would be pretty simple, but it's
> > giving me trouble.
> >
> > Given a list, say [1,2,3], I'd like to be able to generate an infinite
> > list of random elements from that list, in this case maybe
> > [1,2,1,3,2,1,3,2,3,1,2,...]. I'm using IO for random purely due to
> > laziness (my own, not Haskell's).
> >
> > I was thinking the best way to do this might be to first write this
> function:
> >
> > randomElts :: [a] -> [IO a]
> > randomElts [] = []
> > randomElts [x] = repeat (return x)
> > randomElts xs = repeat r
> >   where
> >   bds = (1, length xs)
> >   xArr = listArray bds xs
> >   r = do
> >     i <- randomRIO bds
> >     return (xArr ! i)
> >
> > Then I should be able to do this in ghci:
> >
> > > sequence . take 5 \$ randomElts [1,2,3]
> > [*** Exception: stack overflow
> >
> > Any idea what's going on? I thought laziness (Haskell's, not my own)
> > would save me on this one.
>
> I don't get that result. However, you can't compute an infinite random
> list in IO without using something like unsafeInterleaveIO. However,
> you will probably be interested in randoms/randomRs, which take a
> random generator, and give an infinite list of results.
>
> Using that, we could write something like:
>
> randomElts :: [a] -> IO [a]
> randomElts [] = return []
> randomElts xs = do g <- newStdGen
>                    return (map (xArr !) (randomRs bds g))
> where bds = (1, length xs)
>        xArr = listArray bds xs
>
> which for a nonempty input list, gives an infinite list of
> pseudorandom elements of that input list.
>
> - Cale
> _______________________________________________