Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do i use getStdGen in a function

Tags:

random

haskell

I'm new to haskell, especially the Random type, and I was looking through learnyouahaskell tutorials when I came across this

import System.Random  

main = do  
    gen <- getStdGen  
    putStr $ take 20 (randomRs ('a','z') gen) 

However, when I try to use this in a function, this fails (i.e)

genrandTF:: Int -> StdGen -> [Bool]
genrandTF number gen =  take number (randomRs (True, False) gen)

and calling it via

genrandTF 20 getStdGen

why is that?

-update-

The error I'm getting is

<interactive>:116:15:
    Couldn't match expected type `StdGen' with actual type `IO StdGen'
    In the second argument of `genrandTF', namely `(getStdGen)'
    In the expression: genrandTF 20 (getStdGen)

When I change it to type IO StdGen, I'm unable to compile as I get this message:

No instance for (RandomGen (IO StdGen))
  arising from a use of `randomRs'
In the second argument of `take', namely
  `(randomRs (True, False) gen)'
In the expression: take number (randomRs (True, False) gen)
In an equation for `genrandTF':
    genrandTF number gen = take number (randomRs (True, False) gen)
like image 538
Gwen Wong Avatar asked Nov 12 '14 21:11

Gwen Wong


1 Answers

This is a common mistake of beginners. getStdGen is a value which has the type IO StdGen; in other words it is not a StdGen but rather a computer program which, when it completes, will contain something which Haskell can use as a StdGen.

You'll need to either run the program to get the StdGen (via unsafePerformIO -- as the name implies this breaks several safety guarantees in Haskell), or you'll need to combine the function with the program to make a new program. (Idiomatically, Haskell I/O is a bunch of Haskell operations interleaved with I/O operations.)

The easiest way to do what you're trying to do would be:

fmap (genrandTF 20) getStdGen

which uses the Functor instance for IO.

like image 174
CR Drost Avatar answered Sep 20 '22 15:09

CR Drost