[Haskell-beginners] Random Numbers with the State Monad

Thomas Jakway tjakway at nyu.edu
Fri Feb 12 01:14:08 UTC 2016


I'm having a bad time using the State monad to generate random numbers 
without carrying around a lot of StdGens manually.
I have this snippet in the IO monad:

     ... IO stuff ...
     gen <- getStdGen
     let (numPlayers, numMatches) = (evalState genRandVariables gen) :: 
(Integer, Integer)
     ... More IO stuff ...

     where maxRandPlayers = 10 :: Integer
           minRandMatches = 10 :: Integer
           maxRandMatches = 100 :: Integer
           genRandVariables = (do
                 np <- randomR (1, maxRandPlayers) --minimum 1 other player
                 nm <- randomR (minRandMatches, maxRandMatches)
                 return (np, nm)) :: State StdGen (Integer, Integer)


I get this error message:
test/Jakway/Blackjack/Tests/IntegrationTests/MatchTests.hs:53:23:
     Couldn't match expected type ‘StateT
                                     StdGen 
Data.Functor.Identity.Identity Integer’
                 with actual type ‘g0 -> (Integer, g0)’
     Probable cause: ‘randomR’ is applied to too few arguments
     In a stmt of a 'do' block: np <- randomR (1, maxRandPlayers)
     In the expression:
         (do { np <- randomR (1, maxRandPlayers);
               nm <- randomR (minRandMatches, maxRandMatches);
               return (np, nm) }) ::
           State StdGen (Integer, Integer)

test/Jakway/Blackjack/Tests/IntegrationTests/MatchTests.hs:54:23:
     Couldn't match expected type ‘StateT
                                     StdGen 
Data.Functor.Identity.Identity Integer’
                 with actual type ‘g1 -> (Integer, g1)’
     Probable cause: ‘randomR’ is applied to too few arguments
     In a stmt of a 'do' block:
       nm <- randomR (minRandMatches, maxRandMatches)
     In the expression:
         (do { np <- randomR (1, maxRandPlayers);
               nm <- randomR (minRandMatches, maxRandMatches);
               return (np, nm) }) ::
           State StdGen (Integer, Integer)

What's really baffling to me is I feel like this is how it *should* 
look--that the whole point of the state monad is to *not* have to 
explicitly pass the StdGen to randomR.  What am I doing wrong?


More information about the Beginners mailing list