Instance Bool
與Instance Int
共享執行,但是共享的代碼是randomR
的代碼,它使用一個範圍。我們可以驗證這一點使用快速檢查:
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.
您也可以看看definition of the 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)
這個問題是基於一個錯誤的前提:實現「Bool」的'random'離子不需要(也不會)爲'Int'調用'random'的實現。 –
我將我的示例代碼放在一個名爲「Learn you Haskell for Great Good!」的教程系列中。由於我是初學者,我甚至不知道我的前提是錯誤的 – user38352
你能解釋一下你期望的結果嗎?爲什麼? – user2407038