[Haskell-cafe] Generating a random list
Luke Palmer
lrpalmer at gmail.com
Sat Mar 1 11:15:03 EST 2008
On Sat, Mar 1, 2008 at 8:18 AM, Milos Hasan <mhasan at cs.cornell.edu> wrote:
> Here's a minimal summing example that illustrates the difference. The
> following works fine, since the elements are generated lazily and summed
> on the fly, as expected:
>
> randFloats :: [Float]
> randFloats = randoms (mkStdGen 0)
>
> main = do
> let xs = take 1000000 randFloats
> print $ sum xs
>
> But this overflows, because the list is created before being summed, and
> the take function goes into awfully deep recursion:
>
> randFloats :: [Float]
> randFloats = randoms (mkStdGen 0)
>
> main = do
> xs <- return $ take 1000000 randFloats
> print $ sum xs
It is definitely the strictness analyzer biting you here. In ghci,
the behavior of these two programs is identical (stack overflow). As
kalman said, if you replate sum with foldl' (+) 0 in each of these
programs, the behavior is still identical (correct).
As a side note, one of the monad laws is this:
return x >>= f = f x
So your two programs are semantically equivalent (there's nothing
about IO that forces the evaluation of the list).
If you're building some sort of tree out of these values, you're going
to want to make sure that whatever fold you do (be it using foldl' or
recursion)
is strict, so that you don't get a huge thunk that doesn't have any information.
Luke
More information about the Haskell-Cafe
mailing list