Números aleatorios (Random) en Haskell

Conseguir un puto número aleatorio en Haskell no es nada trivial. He estado buscando algunas soluciones, y al final he sacado el siguiente código, que no sé sí será el más correcto, pero funciona:

miRandom =
do
newStdGen
g<-getStdGen
let
a = 0::Int
b = 20::Int
x = randomR (a, b) g
print x

Que imprime por pantalla:

(17,1295529924 1123184626)
:: IO ()

La función miRandom imprime por pantalla la representación de la variable x que es del tipo (Int, StdGen). Vamos, el 17 es el número aleatorio entre 0 y 20, que son las variables a y b, y los otros dos números largos y extraños que forman el segundo campo de la tupla son un nuevo StdGen, que explicaremos después.
StdGen
Tipo de dato que representa un generador de números aleatorios. Necesario para todas las funciones encargadas de la generación del número.

getStdGen
Función que devuelve el generador de números aleatorios por defecto.

newStdGen:
Función que "actualiza" el generador de números aleatorios por defecto.

randomR
::(Random a, RandomGen b) => (a,a) -> b -> (a,b)

Recibe una tupla con los límites entre los que queremos sacar el elemento aleatorio y, como segundo un generador de números aleatorios, siempre del tipo StdGen.

En realidad, por defecto, pueden sacarse elementos aleatorios de los siguientes tipos de datos: Bool, Int, Integer, Char, Float, Double

Importante: clases genéricas (como Num) NO funcionarán en esta función.

Todo eso está muy bien, sí, pero hay un problema, y es que si ahora creamos esta función:
miRandom2 =
do
newStdGen
g<-getStdGen
let
a = 0::Int
b = 20::Int
x = randomR (a, b) g
y = randomR (a, b) g
print x
print y

y la ejecutamos, obtenemos esto:
(12,1295689980 1326707213)
(12,1295689980 1326707213)
:: IO ()

Es decir, el número aleatorio generado (el 12) es el mismo para ambas variables. ¿Casualidad? Podría ser. Pero si ejecutamos la función infinitas veces esas infinitas veces y las siguientes, los números aleatorios generados por randomR serán siempre los mismos para x e y. ¿Por qué? Porque el generador de números aleatorios siempre es el mismo, g y a partir de él siempre se generan los mismos números.

Solución: ¿Recuerdas que randomR devuelve una tupla en la que el primer miembro es el elemento aleatorio y el segundo dos números grandes y extraños? Pues ese segundo miembro es un nuevo elemento de tipo StdGen, distinto al original recibido por la función, y que utilizaremos para encontrar el siguiente número aleatorio. Entonces:
miRandom3 =
do
newStdGen
g<-getStdGen
let
a = 0::Int
b = 20::Int
x = randomR (a, b) g
y = randomR (a, b) (snd x)
print x
print y

Que tiene como salida:
(14,1994861249 30671636)
(16,413980776 402357293)
:: IO ()

Para terminar, recalcar que el uso de newStdGen es necesario para actualizar el generador de números aleatorios por defecto.

Si no lo hiciéramos, en cada una de las ejecuciones de miRandom3 los números aleatorios serían los mismos. Es decir, si en la primera ejecución fst x fuera 13 y fst y fuera 15, en las sucesivas ejecuciones de miRandom3, fst x y fst y continuarían valiendo 13 y 15, porque ambas generaciones, al no haber sido invocada newStdGen, partirían del mismo StdGen por defecto.