[英]How does Haskell determine what kind of boolean a randomly generated number is?
請考慮以下兩組代碼:
random (mkStdGen 1) :: (Int, StdGen)
-- returns (7918028818325808681,545291967 2103410263)
random (mkStdGen 1) :: (Bool, StdGen)
-- returns (True,80028 40692)
random (mkStdGen 949488) :: (Int, StdGen)
-- returns (9159618695640234475,587416689 2103410263)
random (mkStdGen 949488) :: (Bool, StdGen)
-- returns (False,1485632275 40692)
為什么7918028818325808681
轉換為True
而9159618695640234475
轉換為False
?
Instance Bool
與Instance Int
共享實現,但是共享的代碼是randomR
的代碼,需要一定范圍。 我們可以使用QuickCheck進行驗證:
Prelude> import Test.QuickCheck
Prelude Test.QuickCheck> import System.Random
Prelude Test.QuickCheck System.Random> :{
Prelude Test.QuickCheck System.Random| prop seed = let
Prelude Test.QuickCheck System.Random| gen = mkStdGen seed
Prelude Test.QuickCheck System.Random| b = fst (random gen)
Prelude Test.QuickCheck System.Random| i = fst (randomR (0,1) gen)
Prelude Test.QuickCheck System.Random| in if b then i == 1 else i == 0
Prelude Test.QuickCheck System.Random| :}
Prelude Test.QuickCheck System.Random> quickCheck prop
+++ OK, passed 100 tests.
您還可以查看instance Random Bool
的定義 ,您將在其中找到以下代碼:
instance Random Bool where
randomR (a,b) g =
case (randomIvalInteger (bool2Int a, bool2Int b) g) of
(x, g') -> (int2Bool x, g')
where
bool2Int :: Bool -> Integer
bool2Int False = 0
bool2Int True = 1
int2Bool :: Int -> Bool
int2Bool 0 = False
int2Bool _ = True
random g = randomR (minBound,maxBound) g
非常重要,您要調用randomR (0,1)
,然后將0
映射為False
,將1
映射為True
:
> random (mkStdGen 949488) :: (Bool, StdGen)
(False,1485632275 40692)
> randomR (0,1) (mkStdGen 949488) :: (Int, StdGen)
(0,1485632275 40692)
> random (mkStdGen 1) :: (Bool, StdGen)
(True,80028 40692)
> randomR (0,1) (mkStdGen 1) :: (Int, StdGen)
(1,80028 40692)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.