Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pick a random list element in a pure function?

Tags:

haskell

I want to make a Haskell function that can pick out a random number from a given list. My type signature is:

randomPick :: [a] -> a 

What should I do?

like image 818
user345662 Avatar asked May 28 '10 02:05

user345662


2 Answers

Part of the definition of a "pure" function in Haskell is that it is referentially transparent, that is, interchangeable with the result of evaluating it. This implies that the result of evaluating it must be the same every time. Ergo, the function you want isn't possible, I'm afraid. To generate random numbers in Haskell, a function needs to do one of two things:

Take and return a pseudorandom number generator, e.g.:

randomPick :: RNG -> [a] -> (a, RNG)

Or use IO to access randomness from "the outside world":

randomPick :: [a] -> IO a

Both styles are provided by the module System.Random. Also, in the former case, passing the PRNG around can be abstracted out using the State monad, or perhaps a special-purpose Random monad.

like image 82
C. A. McCann Avatar answered Oct 08 '22 23:10

C. A. McCann


What you've described can't be done in pure functional code.

Pure functional code implies that you will get the same output for the same input, every time. Since a randomizing function, by definition, gives you different output for the same input, this is impossible in pure functional code.

Unless you pass around an extra value as explained in @camccann's answer. Technically, it doesn't even have to be as advanced as an RNG, depending on your needs. You could pass around an integer, and multiply it by 10 and subtract 3 (or whatever), then take the modulo of that to find your index. Then your function remains pure, but you do directly control the randomness.

Another option is to use RandomRIO to generate a number in a range, which you can then use to select an index from the list. This will require you to enter the IO monad.

like image 24
Mark Rushakoff Avatar answered Oct 08 '22 23:10

Mark Rushakoff