2017-08-25 110 views
0

我之前創建了此函數來生成整數範圍爲(m,n)的隨機數。在Haskell中運行多個函數

giveRand :: Random c => c -> c -> c 
giveRand m n = unsafePerformIO . getStdRandom $ randomR (m,n) 

從這種情況下,我想多次使用相同的參數運行它,這樣它會返回我隨機生成值的列表中給定的範圍內。我嘗試了複製功能,但它只複製了giveRand的結果。它沒有創建函數的多個副本並重新評估它。

從這個問題我想知道是否有一個函數,允許我用相同的參數多次運行任何函數。我會問這個例子,即使輸入範圍相同,也可能出現不同的值。

那麼,Haskell中是否有任何函數使我能夠使用相同的參數多次運行函數?

+2

你是不可能找到任何標準組合子要做到這一點,因爲所有通用代碼將被編寫爲標準假設,即Haskell函數爲相同的參數返回相同的結果。您使用'unsafePerformIO'扔掉的設施是您可以找到允許您將「生成隨機數」轉換爲「生成隨機數列表」的代碼的地方。 – Ben

+6

我第二@本的觀點。 (我們Bens必須堅持在一起。)'unsafePerformIO'是你混亂的根源。我強烈建議忘記存在'unsafePerformIO'。這意味着專家用戶 - 這個名字是爲了嚇跑你!你需要的情況確實非常罕見,這不是其中之一。花費你的努力學習如何使用'IO'類型來代替。這很值得! –

回答

8

忘記unsafePerformIO;承認你正在做一些有狀態的事情。具體方法如下:

Control.Monad System.Random> replicateM 3 (randomRIO (5,7)) 
[6,7,5] 

如果你不能這樣做IO,你也可以讓有狀態的明確與State單子:

Control.Monad.State System.Random> runState (replicateM 3 (state (randomR (5,7)))) (mkStdGen 0) 
([7,7,5],1346387765 2103410263) 
+1

或者,如果您不關心最終生成器狀態,則可以乾淨地使用'evalState' - 這非常類似於由'runState'組成的'fst'。例如:'evalState(replicateM 3(state(randomR(5,7))))(mkStdGen 0) [7,7,5]' –