簡體   English   中英

如何解壓縮任意長度的IO Bool列表

[英]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調用一直推入其中
  • make gens使用replicateM而不是replicate

您可能需要訪問http://codereview.stackexchange.com以獲得更全面的反饋。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM