
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?