簡體   English   中英

從非一元函數獲取隨機數

[英]Getting random numbers from non-monadic functions

因此,我的目標是能夠調用非一元函數並使其返回隨機值。

getNums :: [Int] -- this only works when the type signature is "IO [Int]"
getNums = getListFromIO 10

getListFromIO :: Int -> IO [Int]
getListFromIO n = do
  gen <- newStdGen
  return $ generateList n gen

generateList :: Int -> StdGen -> [Int]
generateList n gen = take n $ randomRs (1,9) $ gen

如果我調用getListFromIO ,一切都很好。 我得到了我寶貴的整數隨機列表,並且每次都不同。 但是每個調用它的函數都必須使用IO [Int]它的類型簽名。 我不要

如何構造此結構,以便能夠獲得[Int]類型的隨機數列表?

您不能,不應該也不需要這樣做。

您聲稱所有使用getNums :: IO [Int]函數的類型都必須具有IO 這是不正確的。 您可以通過多種方式使用IO [Int]操作計算的[Int]值,例如:

main = do
  ints <- getNums -- ints is now of type [Int]
  return (map (+1) ints) -- map (+1) does not have IO in its type.

這是引入FunctorApplicativeMonad類型類的原因之一:當您希望避免在任何地方處理IO時,提供一種一致的方式來處理IO [Int]類的東西。

IO的目的恰恰是不允許純代碼產生副作用。 所有非純代碼都必須在IO monad中運行。 隨機性還基於狀態或從外部資源讀取(全局狀態)。 因此,沒有黑客,您嘗試的事情是不可能的。 我強烈敦促您不要使用任何黑客手段。 這些黑客完全繞過了類型系統提供的安全性; 僅應將它們限制在本地安全的hack上,主要是在類型系統不是明智的且需要令人信服的情況下。 但事實並非如此-故意使一個純函數表現得像一個非純函數,絕不是一個本地化的技巧,因為任何調用它的代碼都將繼承損壞的語義,而無法跟蹤純函數的結束位置和非純函數。純度開始。

最好將代碼重新設計為不需要在純代碼中生成隨機數。 只需從駐留在IO中的代碼層次結構的高層傳遞隨機性即可。

暫無
暫無

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

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