简体   繁体   中英

How does the `randoms` function in Haskell work?

I'm following the Learn You A Haskell book to learn Haskell, and I am having trouble understanding the randoms function. The book defines the function as:

randoms' :: (RandomGen g, Random a) => g -> [a]  
randoms' gen = let (value, newGen) = random gen in value:randoms' newGen    

Now the way I see this function is that it calls itself recursively and appends the return value to the list value . What I don't understand is how the function returns because every time it just calls itself with a new random seed!

I think the confusing part might be the use of : in the return value.

value:randoms' newGen 

This is a list, with the first item of value , and the rest of the list is what is returned by the recursive call to randoms' newGen .

What I don't understand is how the function returns because every time it just calls itself with a new random seed!

Because of laziness, it will only call itself if you try to access the second (or later) item of the returned list. This list isn't, and couldn't be in memory, at once. Lists in Haskell are more like recipes... until you try to access an element, Haskell doesn't try to work out what it is.

As a crude comparison, instead of trying to think of how an infinite list could be returned, consider how a Python generator is capable of "returning" an infinite list: by yield ing one element at a time, as they're required.

The entire list isn't returned at once. Each element is evaluated as it's needed, and the function only recurses as it needs to.

Note, I'm not claiming Haskell's laziness works the same way as Python's generators, but it may be a helpful comparison to keep in mind when thinking about functions like these.

See the other answer to get an explanation of why this is happening.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM