Skip to content
GitLab
Projects Groups Topics Snippets
  • /
  • Help
    • Help
    • Support
    • Community forum
    • Submit feedback
  • Register
  • Sign in
  • GHC GHC
  • Project information
    • Project information
    • Activity
    • Labels
    • Members
  • Repository
    • Repository
    • Files
    • Commits
    • Branches
    • Tags
    • Contributor statistics
    • Graph
    • Compare revisions
    • Locked files
  • Issues 5.5k
    • Issues 5.5k
    • List
    • Boards
    • Service Desk
    • Milestones
    • Iterations
  • Merge requests 626
    • Merge requests 626
  • CI/CD
    • CI/CD
    • Pipelines
    • Jobs
    • Artifacts
    • Schedules
    • Test cases
  • Deployments
    • Deployments
    • Releases
  • Analytics
    • Analytics
    • CI/CD
    • Code review
    • Insights
    • Issue
    • Repository
  • Wiki
    • Wiki
  • Snippets
    • Snippets
  • Activity
  • Graph
  • Create a new issue
  • Jobs
  • Commits
  • Issue Boards
Collapse sidebar
  • Glasgow Haskell CompilerGlasgow Haskell Compiler
  • GHCGHC
  • Issues
  • #3620
Closed
Open
Issue created Oct 28, 2009 by Ghost User@ghostContributor

The seeds generated by split are not independent

Suppose we split a seed into two like this:

split' :: StdGen -> (StdGen, StdGen)
split' g = (g12, g21)
  where (_, g12) = split g1
        (g21, _) = split g2
        (g1, g2) = split g

Since g1 and g2 are independent, g12 and g21 ought to be too. But they're not! If we use both of g12 and g21 to generate a random number in the range [0..10], then the two numbers ought to be equal 1/11 of the time. In fact, they're never equal. Here is a test program that ought to return True 1/11 of the time but actually always returns False:

sample :: StdGen -> (Int, Int)
sample g = (fst (randomR (0, 10) g1),
            fst (randomR (0, 10) g2))
   where (g1, g2) = split' g
test :: StdGen -> Bool
test g = fst (sample g) == snd (sample g)

I attached a program that prints the distribution of values from test for other ranges than [0..10]. The distribution is always quite bad no matter what the range is.

The upshot of all this is that the following QuickCheck (version 2) property always passes, even though it's false:

import Test.QuickCheck
import Text.Show.Functions

newtype Eleven = Eleven Int deriving Eq

instance Arbitrary Eleven where
  arbitrary = fmap Eleven (choose (0, 10))

prop :: (Int -> Eleven) -> Bool
prop f = f 5 /= f 6
Trac metadata
Trac field Value
Version 6.11
Type Bug
TypeOfFailure OtherFailure
Priority normal
Resolution Unresolved
Component libraries/random
Test case
Differential revisions
BlockedBy
Related
Blocking
CC
Operating system
Architecture
To upload designs, you'll need to enable LFS and have an admin enable hashed storage. More information
Assignee
Assign to
Time tracking