15th
Randoms and Haskell
Right now I’m on chapter 15 of my RWH book. This one talks about problems that get complicated without the use of a Monad, one of them is the System.Random API of Haskell. I’m going to start by introducing two typeclasses that this module exports for clarity’s sake:
RandomGen: aRandomGenrepresents an state that holds the random input, I like to think of it like a stream of some sort (stdin, stdout).Random a: This typeclass is the abstraction of a Random value, all the common types of Haskell implement this typeclass (String, Integer, Float, Int, etc.)
What confused me for sometime, and I actually had to analyze throughly was how the interactions between the Random API and the IO Monad worked.
The following code was the one that got me thinking:
import System.Random hiding (next)
randomsIO :: Random a => IO [a]
randomsIO =
getStdRandom $ \g ->
let (a, b) = split g
in (randoms a, b)
Where the IO [a] comes from?, if this anonymous function is returning a type
([a], RandomGen) instead of an IO [a]. This got me really confused, at some point I thought that a StdGen was an instance of an IO, but realized pretty quickly that IO is not a classtype, but an instance of Monad.
The best way to figure this out was checking the types of getStdRandom:
getStdRandom :: (StdGen -> (a, StdGen)) -> IO a
getStdRandom receives as it’s first parameter, a function that receives a StdGen and then return a tuple with the first position being some value of an anonymous type and second position being a (probably altered) StdGen, the return of the getStdRandom is whatever the parameter function returned on the first parameter of the tupple, wrapped in an IO Monad.
So the only way to work with a random function, is with the use of a getStdRandom like interface, why is that?. I’m assuming this is a way to provide “factory functions” for random generated data, a pretty clever choice (yet confusing, at least for me). Another important reason is that this way it will keep things pure, you don’t have to use the IO Monad on the random functions definitions.
Haskell is fun :-).
