2014-12-07 88 views
2

我想在Haskell中生成一個隨機數列表。如何生成Haskell中的隨機數列表

Step 1 : declare an empty Int List 
Step 2 : Generate a random number between 1 to 50 
Step 3 : Add that number at the end of the List. 
Step 4 : Repeat Step 2 and 3 for 5 times. 

我已經使用數組寫了代碼。

import System.Random 
import Data.Array.IO 
main = do 
    arr <- newArray (1,5) 0 :: IO (IOArray Int Int) 

    forM_ [1..5] (\i -> do 
     v <- getStdRandom(randomR (1,50)) 
     writeArray arr i v) 

    forM_ [1..5] (\i -> do 
     a <- readArray arr i   
     print (a)) 

樣本輸出是這樣的: -

Prelude> main 
32 
14 
27 
23 
33 

如何實現這個使用列表。可能使用MVar或TVar列表。提前致謝。

+0

想想這個的方法並不是說「從一個空列表開始,然後填充它」,而是「一個N個隨機數列表由一個隨機數組成,後跟一個N-1個隨機數列表數字」。你寫的是翻譯你想用Java或C++寫的東西。 – 2014-12-07 14:33:53

+0

[Data.Random.Normal](https://hackage.haskell.org/package/normaldistribution-1.1.0.1/docs/Data-Random-Normal.html)模塊可讓您執行諸如'mkNormals 12345'之類的操作來獲取隨機值的無限列表(12345是種子)。 – 2014-12-07 19:20:46

+0

@ PaulJohnson,謝謝你的建議。 – 2014-12-08 04:37:51

回答

5

步驟1:聲明空Int列表...

不這樣做。創建一個空的東西然後填充它很少是一個好主意。有時候,出於性能方面的原因,創建一個未初始化的數組(不是空的,而是「真空的」),然後在事實之後定義內容會很聰明 - 這基本上就是您在代碼中發生的事情。也是合理的:從一個空的Set開始逐漸填滿;這可以在純粹的功能狀態monad中很好地完成。

但是對於列表(或數組),從空開始從不會獲得任何東西;爲什麼不正確定義完整結果列表馬上?它是如此簡單:

do 
     ... 
     randList <- forM [1 .. lLength] $ \_i -> randomRIO (1,50) 
     ... 

請注意,這不是forM_forM,它會自動收集在一個列表–的結果就是你想要的!我實際上並不需要索引參數(因此i變量的_前綴)。我也可以寫作mapM (const $ randomRIO (1,50)) [1 .. lLength]或者簡單地replicateM lLength $ randomRIO (1,50)作爲user3237465的評論。

+1

如果你不需要索引參數,那麼你可以只寫'replicateM lLength(randomRIO(1,50))'。 – user3237465 2014-12-07 14:26:47

+0

非常感謝@leftaroundabout – 2014-12-08 04:30:33

+0

謝謝@ user3237465。 – 2014-12-08 04:31:31