[英]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.
這是引入Functor
, Applicative
和Monad
類型類的原因之一:當您希望避免在任何地方處理IO
時,提供一種一致的方式來處理IO [Int]
類的東西。
IO的目的恰恰是不允許純代碼產生副作用。 所有非純代碼都必須在IO monad中運行。 隨機性還基於狀態或從外部資源讀取(全局狀態)。 因此,沒有黑客,您嘗試的事情是不可能的。 我強烈敦促您不要使用任何黑客手段。 這些黑客完全繞過了類型系統提供的安全性; 僅應將它們限制在本地安全的hack上,主要是在類型系統不是明智的且需要令人信服的情況下。 但事實並非如此-故意使一個純函數表現得像一個非純函數,絕不是一個本地化的技巧,因為任何調用它的代碼都將繼承損壞的語義,而無法跟蹤純函數的結束位置和非純函數。純度開始。
最好將代碼重新設計為不需要在純代碼中生成隨機數。 只需從駐留在IO中的代碼層次結構的高層傳遞隨機性即可。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.