I'm writing a program that should be able to simulate many instances of trying the martingale betting system with roulette. I would like main
to take an argument giving the number of tests to perform, perform the test that many 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 list of Bool
that I could filter over to count successes, I have a list of IO Bool
and I don't understand how I can filter over that.
Here's 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"
Like I have in my comments, I basically want to map (<-)
over my list of IO Bool
, but as I understand it, (<-)
isn't actually a function but a keyword. Any help would be greatly appreciated.
map martingale gens
will give you something of type [IO Bool]
. You can then use sequence
to unpack it:
sequence :: Monad m => [m a] -> m [a]
A more natural alternative is to use mapM
directly:
mapM :: Monad m => (a -> m b) -> [a] -> m [b]
i.e. you can write
results <- mapM martingale gens
Note - even after doing it this way, your code feels a bit unnatural. I can see some advantages to the structure, in particular because martingale'
is a pure function. However having something of type IO StdGen -> IO Bool
seems a bit odd.
I can see a couple of ways to improve it:
martingale'
return an IO
type itself and push the newStdGen
call all the way down into itgens
use replicateM
rather than replicate
You may want to head over to http://codereview.stackexchange.com for more comprehensive feedback.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With