mercredi 29 septembre 2021

How to use do notation with System.Random.Stateful

I want to use do notation to combine pseudo-random values:

g :: StdGen
g = mkStdGen 100

example1 :: Bool
example1
  = fst
  $ runState
    (do x <- state (uniformR (False,True))
        y <- state (uniformR (False,True))
        return $ x == y
    )
    g

Function uniformR is defined in terms of the System.Random.Stateful module:

uniformR :: (RandomGen g, UniformRange a) => (a, a) -> g -> (a, g)
uniformR r g = runStateGen g (uniformRM r)

so in my example, it seems silly for uniformR to create and run state, only for my example to create and run state again.

Is there a way to rewrite example 1, using System.Random.Stateful and do notation?

This is the only thing I could get to work (which is ridiculous):

example3 :: Bool
example3
  = fst
  $ runStateGen
    g
    (do x <- uniformRM (False,True)
        y <- uniformRM (False,True)
        return $ do x' <- x
                    y' <- y
                    return $ x'==y')

It seems like what I need is some type of monad transformer?




Aucun commentaire:

Enregistrer un commentaire