Ammlan Ghosh
Ammlan Ghosh

Reputation: 375

How to generate List of random numbers in Haskell

I want to generate a list of random numbers in Haskell.

Step 1 : declare an empty Int List 
Step 2 : Generate a random number between 1 to 50
Step 3 : Add that number at the end of the List.
Step 4 : Repeat Step 2 and 3 for 5 times.

I have written the code using an Array.

import System.Random 
import Data.Array.IO
main =  do 
     arr <- newArray (1,5) 0 :: IO (IOArray Int Int)

     forM_ [1..5] (\i -> do
        v <- getStdRandom(randomR (1,50))
        writeArray arr i v)

     forM_ [1..5] (\i -> do 
        a <- readArray arr i        
        print (a))

A sample output is like this: -

Prelude> main
32
14
27
23
33

How to implement this using a List. May be using MVar or TVar List. Thanks in advance.

Upvotes: 2

Views: 2330

Answers (1)

leftaroundabout
leftaroundabout

Reputation: 120711

Step 1 : declare an empty Int List...

don't do that. Creating an empty thing an then filling it up is seldom a good idea. Sometimes, for performance reasons, it can be clever to create an uninitialised array (not empty, but "vacuous") and then define the contents after the fact – that's basically what happens in you code. Also reasonable: starting with an empty Set and progressively filling it up; this can be done nicely in a purely-functional state monad.

But for lists (or arrays), starting empty never gains you anything; why not properly define the full result list straight away? It's as simple as this:

    do
      ...
      randList <- forM [1 .. lLength] $ \_i -> randomRIO (1,50)
      ...

Note that this is not forM_ but forM, which automatically gathers the results in a list – just what you want! I don't actually need the index parameter (hence the _ prefix of the i variable). I could also have written mapM (const $ randomRIO (1,50)) [1 .. lLength], or indeed simply replicateM lLength $ randomRIO (1,50), as user3237465 remarks.

Upvotes: 5

Related Questions