[Haskell-beginners] To use random number monad inside function
Thomas Davie
tom.davie at gmail.com
Wed Jan 28 02:23:07 EST 2009
On 28 Jan 2009, at 04:33, Erick González wrote:
> Hi:
> Haskell' s way of random number generation is strange to me, but I
> know how to do that. I' d like to know how can I call random numbers
> generated on the screen inside a classic function. I mean, I need to
> know the way of calling random numbers (one different every time
> that I run) inside a function. Please, Could anybody help me?
There's a problem with doing this – Haskell guarentees that no matter
what (well, okay, not quite, but unsafePerformIO doesn't count), if
you give the same arguments to a function, you'll get the same
results. This is known as referential transparency. This is what
gets us some of the biggest gains from the language (e.g. without it,
we wouldn't be allowed to use our choice of non-strict evaluation
order, we wouldn't be allowed to automatically parallelise, etc).
So, how is this problem solved? In a couple of interesting ways.
First is the way you've already seen, we can lock random number
generation in a monad (usually the IO monad). What this does, is it
guarentees that the same IO action will always be returned by the
function, but when that IO action gets shoved into the runtime, it can
do any non-referentially transparent thing it likes, but that's
"okay", because we're out of haskell land.
Understandably, this isn't the nicest way to do things, because it
locks us in the IO monad, and in the evaluation of the action we lose
all the advantages we had. Not only that, but the programming style
is fairly imperative. So, we can think of a couple of ways round the
restruction – in order to give different outputs, we must have
different inputs, so lets think about a couple of ways of doing that:
Firstly, we can pass a 'seed' into our pure function with which to
generate further random numbers. Secondly, we can use Haskell's
ability to deal with infinitely large data structures, and pass in an
infinitely long list of 'random' numbers. Here's the second one:
main = do
seed <- do something to generate a seed
interact $ pureMain . randoms $ seed
pureMain :: [Int] -> String -> String
pureMain rs "jam" = show (take 20 rs)
Hope that helps
Bob
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.haskell.org/pipermail/beginners/attachments/20090128/96a913bb/attachment.htm
More information about the Beginners
mailing list