How can I unpack an arbitrary list of lengths IO Bool

I am writing a program that should be able to simulate many examples of attempts at a martingale betting system with roulette. I would like main take an argument giving the number of tests to run, run the test multiple times, and then print the number of wins divided by the total number of tests. My problem is that instead of ending up with a Bool list that I could filter for success counts, I have an IO Bool list and I don’t understand how I can filter it.

Here is the source code:

 -- file: Martingale.hs -- a program to simulate the martingale doubling system import System.Random (randomR, newStdGen, StdGen) import System.Environment (getArgs) red = [1,3,5,7,9,12,14,16,18,19,21,23,25,27,30,32,34,36] martingale :: IO StdGen -> IO Bool martingale ioGen = do gen <- ioGen return $ martingale' 1 0 gen martingale' :: Real a => a -> a -> StdGen -> Bool martingale' bet acc gen | acc >= 5 = True | acc <= -100 = False | otherwise = do let (randNumber, newGen) = randomR (0,37) gen :: (Int, StdGen) if randNumber `elem` red then martingale' 1 (acc + bet) newGen else martingale' (bet * 2) (acc - bet) newGen main :: IO () main = do args <- getArgs let iters = read $ head args gens = replicate iters newStdGen results = map martingale gens --results = map (<-) results print "THIS IS A STUB" 

As in my comments, I basically want to match (<-) over my IO Bool list, but as I understand it, (<-) is actually not a function, but a keyword. Any help would be greatly appreciated.

+5
source share
1 answer

map martingale gens will give you something like [IO Bool] . Then you can use sequence to unpack it:

 sequence :: Monad m => [ma] -> m [a] 

A more natural alternative is to use mapM directly:

 mapM :: Monad m => (a -> mb) -> [a] -> m [b] 

i.e. You can write

 results <- mapM martingale gens 

Note. Even after that, your code looks a little unnatural. I see some advantages for the structure, in particular because martingale' is a pure function. However, having something like IO StdGen -> IO Bool seems a bit strange.

I see several ways to improve it:

  • make martingale' returns the IO type itself and clicks on it to call newStdGen
  • make gens use replicateM , not replicate

You can go to http://codereview.stackexchange.com for more complete feedback.

+10
source

Source: https://habr.com/ru/post/1201608/


All Articles