2017-08-24 2 views
1

Betrachten Sie die folgenden zwei Gruppen von Code:Wie bestimmt Haskell, welche Art von Booleschen Zahlen eine zufällig generierte Zahl ist?

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) 

Warum 7918028818325808681-True nicht übersetzen, aber 9159618695640234475 übersetzt False?

+5

Die Frage basiert auf einem fehlerhaften Prämisse: das Implementieren "zufällig" für "Bool" muss nicht (und nicht) die Implementierung von "zufällig" für "Int" nennen. –

+0

Ich stütze meinen Beispielcode auf eine Lernprogrammreihe mit dem Titel "Lerne ein Haskell für Großartiges!". Da ich ein Anfänger bin, würde ich nicht einmal wissen, dass meine Prämisse fehlerhaft ist. – user38352

+1

Können Sie erklären, was Sie erwarten, dass die Ausgabe ist, und warum? – user2407038

Antwort

8

Die Instance Bool teilt die Implementierung mit Instance Int, aber der Code, der freigegeben wird, ist der für randomR, der eine Reihe nimmt. Wir können dies mit Quick Check überprüfen:

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. 

Sie auch auf der definition of the instance Random Bool schauen können, wo Sie diesen Code finden:

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 

so wichtig, Sie randomR (0,1) fordern und dann die Abbildung 0-False und 1 zu 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) 
Verwandte Themen