[英]How can I unpack an arbitrary length list of IO Bool
我正在編寫一個程序,應該可以模擬許多用輪盤賭嘗試鞅投注系統的實例。 我想main
接受一個參數,給出要執行的測試次數,多次執行測試,然后打印獲勝次數除以測試總次數。 我的問題是,我沒有最終得到Bool
列表,我可以過濾以計算成功,我有一個IO Bool
列表,我不明白我如何過濾它。
這是源代碼:
-- 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"
就像我在評論中所說的那樣,我基本上想在我的IO Bool
列表上映射(<-)
,但據我所知, (<-)
實際上不是一個函數而是一個關鍵字。 任何幫助將不勝感激。
map martingale gens
會給你一些類型[IO Bool]
。 然后,您可以使用sequence
來解壓縮它:
sequence :: Monad m => [m a] -> m [a]
更自然的替代方法是直接使用mapM
:
mapM :: Monad m => (a -> m b) -> [a] -> m [b]
即你可以寫
results <- mapM martingale gens
注意 - 即使這樣做,您的代碼也會感覺有點不自然。 我可以看到結構的一些優點,特別是因為martingale'
是一種純粹的功能。 但是有一些類型的IO StdGen -> IO Bool
似乎有點奇怪。
我可以看到幾種方法來改進它:
newStdGen
martingale'
返回一個IO
類型本身並將newStdGen
調用一直推入其中 gens
使用replicateM
而不是replicate
您可能需要訪問http://codereview.stackexchange.com以獲得更全面的反饋。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.