Random numbers are the kind of thing I use rarely enough that by the time I want to use them, I have forgotten the relevant details, but frequently enough that I get annoyed whenever it happens.
Hopefully these notes will be useful to somebody in a similar situation.
two things to know
(2) randomIO :: Random a => IO a
The one function you really need to know about is
randomIO
(The type of this function is
Random a => IO a
. Don't worry if you do not understand the type; it suffices to know that it involves IO). In this example, we use and generate a random Int:
import System.Random
main =
do r <- randomIO
print (r + 1 :: Int)
-- Note re the ':: Int' above: Haskell can't figure out from
-- the context exactly what type of number you want, so we
-- constrain it to Int
One neat feature is that you can randomly generate anything that implements the
Random
typeclass. In the example below, we generate a random Bool. Notice how we do not do anything differently, except to treat the result as a bool (i.e. by applying
not
to it)
import System.Random
main =
do r <- randomIO
print (not r)
A useful exercise, if you know about typeclasses, is to implement
Random
for one of your own types. The
toEnum
function may be useful.
more advanced stuff
- you can use
randomRIO :: Random a => (a,a) -> IO a
to generate random numbers constrained within a range - Instead of using the functions
randomIO
and randomRIO
, you can separate obtaining a random number generator, from using the generator. Doing so allows you to minimise your reliance on the IO monad. It also makes your code easier to debug, because you can opt to always pass the same generator to it and make life much more predictable. See the functions random
and randomR
for details. - a potentially handy trick is to generate an infinite list of random numbers, which you can then pass to a function. See the
randoms
function for details.
Edit: fixed s/randomR/randomIO/
Random numbers are the kind of thing I use rarely enough that by the time I want to use them, I have forgotten the relevant details, but frequently enough that I get annoyed whenever it happens.
Hopefully these notes will be useful to somebody in a similar situation.
two things to know
(2) randomIO :: Random a => IO a
The one function you really need to know about is
randomIO
(The type of this function is
Random a => IO a
. Don't worry if you do not understand the type; it suffices to know that it involves IO). In this example, we use and generate a random Int:
import System.Random
main =
do r <- randomIO
print (r + 1 :: Int)
-- Note re the ':: Int' above: Haskell can't figure out from
-- the context exactly what type of number you want, so we
-- constrain it to Int
One neat feature is that you can randomly generate anything that implements the
Random
typeclass. In the example below, we generate a random Bool. Notice how we do not do anything differently, except to treat the result as a bool (i.e. by applying
not
to it)
import System.Random
main =
do r <- randomIO
print (not r)
A useful exercise, if you know about typeclasses, is to implement
Random
for one of your own types. The
toEnum
function may be useful.
more advanced stuff
- you can use
randomRIO :: Random a => (a,a) -> IO a
to generate random numbers constrained within a range - Instead of using the functions
randomIO
and randomRIO
, you can separate obtaining a random number generator, from using the generator. Doing so allows you to minimise your reliance on the IO monad. It also makes your code easier to debug, because you can opt to always pass the same generator to it and make life much more predictable. See the functions random
and randomR
for details. - a potentially handy trick is to generate an infinite list of random numbers, which you can then pass to a function. See the
randoms
function for details.
Edit: fixed s/randomR/randomIO/
simple random numbers in Haskell
3 comments:
In "two things to know," I think you meant #2 to be randomIO :: Random a => IO a.
Yes! (as opposed to randomR). Thanks!
Ha, perfect! This was just the level of detail I needed, thanks :)
Post a Comment