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)
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
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With