Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SIMPLE random number generation

I'm writing this after a good while of frustrating research, and I'm hoping someone here can enlighten me about the topic.

I want to generate a simple random number in a haskell function, but alas, this seems impossible to do without all sorts of non-trivial elements, such as Monads, asignation in "do", creating generators, etc.

Ideally I was looking for an equivalent of C's "rand()". But after much searching I'm pretty convinced there is no such thing, because of how the language is designed. (If there is, please someone enlighten me). As that doesn't seem feasible, I'd like to find a way to get a random number for my particular problem, and a general explanation on how it works to get a random number.

prefixGenerator :: (Ord a, Arbitrary a) => Gen ([a],[a])
prefixGenerator = frequency [ 
    (1, return ([],[])),
    (2, do {
            xs1 <- orderedListEj13 ;
            xs2 <- orderedListEj13 ;
            return (xs1,xs2)
       }),
    (2, do {                
            xs2 <- orderedListEj13 ;
            return ((take RANDOMNUMBERHERE xs2),xs2)
       })
    ]

I'm trying to get to grips with QuickCheck but my inability to use random numbers is making it hard. I've tried something like this (by putting an drawInt 0 (length xs2) instead of RANDOMNUMBERHERE)but I get stuck with the fact that take requires an Int and that method leaves me with a IO Int, which seems impossible to transform to an Int according to this.

like image 580
JaimeBarrachina Avatar asked Mar 16 '12 20:03

JaimeBarrachina


People also ask

How do you generate random numbers in basic?

The Small Basic keyword to get a random number is Math. GetRandomNumber(maxNumber) . It will return a random integer between 1 and the input value maxNumber .

What is the formula to generate random numbers?

If we wish to generate a random number between two numbers, we can use the formula: RAND() * (b – a) + a, where a is the smallest number and b is the largest number that we wish to generate a random number for.

What is the best random number generator?

First on this list comes Calucaltor. net's Random Number Generator. If you're looking for something with some solid options for big numbers and a couple of different choices of generator, then this is a great choice to do so. Calculator.net comes with two different versions of its random number generator.

What is random number example?

Random numbers are almost always derived from a set of single-digit decimal numbers: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9. The task of generating random digits from that set of numbers by physical means is not trivial.


2 Answers

As haskell is a pure functional programming language, functions are referentially transparent which means essentially that only a function's arguments determine its result. If you were able to pull a random number out of the air, you can imagine how that would cause problems.

I suppose you need something like this:

prefixGenerator :: (Ord a, Arbitrary a) => Gen ([a],[a])
prefixGenerator = do
  randn <- choose (1,999) -- number in range 1-999
  frequency [ 
    (1, return ([],[])),
    (2, do {
            xs1 <- orderedListEj13 ;
            xs2 <- orderedListEj13 ;
            return (xs1,xs2)
       }),
    (2, do {                
            xs2 <- orderedListEj13 ;
            return ((take randn xs2),xs2)
       })
    ]

In general in haskell you approach random number generation by either pulling some randomness from the IO monad, or by maintaining a PRNG that is initialized with some integer seed hard-coded, or pulled from IO (gspr's comment is excellent).

Reading about how pseudo random number generators work might help you understand System.Random, and this might help as well (scroll down to section on randomness).

like image 113
jberryman Avatar answered Sep 27 '22 21:09

jberryman


You're right in that nondeterministic random (by which I mean "pseudo-random") number generation is impossible without trickery. Functions in Haskell are pure which means that the same input will always produce the same output.

The good news is that you don't seem to need a nondeterministic PRNG. In fact, it would be better if your QuickCheck test used the same sequence of "random" numbers each time, to make your tests fully reproducible.

You can do this with the mkStdGen function from System.Random. Adapted from the Haskell wiki:

import System.Random
import Data.List

randomInts :: Int -> [Int]
randomInts n = take n $ unfoldr (Just . random) (mkStdGen 4)

Here, 4 is the seed that you may want to choose by a fair dice roll.

like image 31
Thomas Avatar answered Sep 27 '22 22:09

Thomas