version 2.0 of random begins
authorCarter Tazio Schonwald <carter.schonwald@gmail.com>
Sun, 15 Jan 2017 19:43:11 +0000 (14:43 -0500)
committerCarter Tazio Schonwald <carter.schonwald@gmail.com>
Sun, 15 Jan 2017 19:43:11 +0000 (14:43 -0500)
25 files changed:
.darcs-boring [deleted file]
.gitignore [deleted file]
.travis.yml [deleted file]
Benchmark/BinSearch.hs [deleted file]
Benchmark/Makefile [deleted file]
Benchmark/RandomnessTest2.hs [deleted file]
Benchmark/RandomnessTest3.hs [deleted file]
Benchmark/SimpleRNGBench.hs [deleted file]
CHANGELOG.md
DEVLOG.md [deleted file]
LICENSE
README.md [deleted file]
Setup.hs
System/Random.hs [deleted file]
prologue.txt [deleted file]
random.cabal
tests/Makefile [deleted file]
tests/T7936.hs [deleted file]
tests/TestRandomIOs.hs [deleted file]
tests/TestRandomRs.hs [deleted file]
tests/all.T [deleted file]
tests/random1283.hs [deleted file]
tests/rangeTest.hs [deleted file]
tests/rangeTest.stdout [deleted file]
tests/slowness.hs [deleted file]

diff --git a/.darcs-boring b/.darcs-boring
deleted file mode 100644 (file)
index 6682606..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-^dist(/|$)
-^setup(/|$)
-^GNUmakefile$
-^Makefile.local$
-^.depend(.bak)?$
diff --git a/.gitignore b/.gitignore
deleted file mode 100644 (file)
index 41c6d8c..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-*~
-
-Thumbs.db
-.DS_Store
-
-GNUmakefile
-dist-install/
-ghc.mk
-
-dist
-.cabal-sandbox
-cabal.sandbox.config
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644 (file)
index 6a03bcb..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-language: haskell
-ghc:
-  - 7.4
-  - 7.6
-  - 7.8
diff --git a/Benchmark/BinSearch.hs b/Benchmark/BinSearch.hs
deleted file mode 100644 (file)
index f611648..0000000
+++ /dev/null
@@ -1,142 +0,0 @@
-
-{- 
- Binary search over benchmark input sizes.
-
- There are many good ways to measure the time it takes to perform a
- certain computation on a certain input.  However, frequently, it's
- challenging to pick the right input size for all platforms and all
- compilataion modes.
-
- Sometimes for linear-complexity benchmarks it is better to measure
- /throughput/, i.e. elements processed per second.  That is, fixing
- the time of execution and measuring the amount of work done (rather
- than the reverse).  This library provides a simple way to search for
- an appropriate input size that results in the desired execution time.
-
- An alternative approach is to kill the computation after a certain
- amount of time and observe how much work it has completed.
- -}
-module BinSearch 
-    (
-      binSearch
-    )
-where
-
-import Control.Monad
-import Data.Time.Clock -- Not in 6.10
-import Data.List
-import System.IO
-import Prelude hiding (min,max,log)
-
-
-
--- | Binary search for the number of inputs to a computation that
---   results in a specified amount of execution time in seconds.  For example:
---
--- > binSearch verbose N (min,max) kernel
---
---   ... will find the right input size that results in a time
---   between min and max, then it will then run for N trials and
---   return the median (input,time-in-seconds) pair.
-binSearch :: Bool -> Integer -> (Double,Double) -> (Integer -> IO ()) -> IO (Integer, Double)
-binSearch verbose trials (min,max) kernel =
-  do 
-     when(verbose)$ putStrLn$ "[binsearch] Binary search for input size resulting in time in range "++ show (min,max)
-
-     let desired_exec_length = 1.0
-        good_trial t = (toRational t <= toRational max) && (toRational t >= toRational min)
-
-        -- At some point we must give up...
-        loop n | n > ((2::Integer) ^ (100::Integer)) = error "ERROR binSearch: This function doesn't seem to scale in proportion to its last argument."
-
-        -- Not allowed to have "0" size input, bump it back to one:
-        loop 0 = loop 1
-
-        loop n = 
-           do 
-              when(verbose)$ putStr$ "[binsearch:"++ show n ++ "] "
-              time <- timeit$ kernel n
-              when(verbose)$ putStrLn$ "Time consumed: "++ show time
-              let rate = fromIntegral n / time
-
-              -- [2010.06.09] Introducing a small fudge factor to help our guess get over the line: 
-              let initial_fudge_factor = 1.10
-                  fudge_factor = 1.01 -- Even in the steady state we fudge a little
-                  guess = desired_exec_length * rate 
-
-   -- TODO: We should keep more history here so that we don't re-explore input space we have already explored.
-   --       This is a balancing act because of randomness in execution time.
-
-              if good_trial time
-               then do 
-                       when(verbose)$ putStrLn$ "[binsearch] Time in range.  LOCKING input size and performing remaining trials."
-                       print_trial 1 n time
-                       lockin (trials-1) n [time]
-
-               -- Here we're still in the doubling phase:
-               else if time < 0.100 
-               then loop (2*n)
-
-               else do when(verbose)$ 
-                         putStrLn$ "[binsearch] Estimated rate to be "
-                                   ++show (round rate::Integer)++" per second.  Trying to scale up..."
-
-                       -- Here we've exited the doubling phase, but we're making our first guess as to how big a real execution should be:
-                       if time > 0.100 && time < 0.33 * desired_exec_length
-                          then do when(verbose)$ putStrLn$  "[binsearch]   (Fudging first guess a little bit extra)"
-                                  loop (round$ guess * initial_fudge_factor)
-                          else    loop (round$ guess * fudge_factor)
-
-        -- Termination condition: Done with all trials.
-         lockin 0 n log = do when(verbose)$ putStrLn$ "[binsearch] Time-per-unit for all trials: "++ 
-                                           (concat $ intersperse " " (map (show . (/ toDouble n) . toDouble) $ sort log))
-                            return (n, log !! ((length log) `quot` 2)) -- Take the median
-
-         lockin trials_left n log = 
-                    do when(verbose)$ putStrLn$ "[binsearch]------------------------------------------------------------"
-                       time <- timeit$ kernel n
-                       -- hFlush stdout
-                       print_trial (trials - trials_left +1 ) n time
-                       -- when(verbose)$ hFlush stdout
-                       lockin (trials_left - 1) n (time : log)
-
-         print_trial :: Integer -> Integer -> NominalDiffTime -> IO ()
-         print_trial trialnum n time = 
-            let rate = fromIntegral n / time
-                timeperunit = time / fromIntegral n
-            in
-               when(verbose)$ putStrLn$ "[binsearch]  TRIAL: "++show trialnum ++
-                                        " secPerUnit: "++ showTime timeperunit ++ 
-                                        " ratePerSec: "++ show (rate) ++ 
-                                        " seconds: "++showTime time
-
-
-
-     (n,t) <- loop 1
-     return (n, fromRational$ toRational t)
-
-showTime ::  NominalDiffTime -> String
-showTime t = show ((fromRational $ toRational t) :: Double)
-
-toDouble :: Real a => a -> Double
-toDouble = fromRational . toRational
-
-
--- Could use cycle counters here.... but the point of this is to time
--- things on the order of a second.
-timeit :: IO () -> IO NominalDiffTime
-timeit io = 
-    do strt <- getCurrentTime
-       io       
-       end  <- getCurrentTime
-       return (diffUTCTime end strt)
-{-
-test :: IO (Integer,Double)
-test = 
-  binSearch True 3 (1.0, 1.05)
-   (\n -> 
-    do v <- newIORef 0
-       forM_ [1..n] $ \i -> do
-         old <- readIORef v
-         writeIORef v (old+i))
--}
diff --git a/Benchmark/Makefile b/Benchmark/Makefile
deleted file mode 100644 (file)
index 69d2d37..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-
-
-OPTS= -O2 -Wall -XCPP
-
-all: lib bench
-
-lib:
-       (cd .. && ghc $(OPTS) --make System/Random.hs)
-
-bench:
-       ghc $(OPTS) -i.. --make SimpleRNGBench.hs 
-
-# When benchmarking against other packages installed via cabal it is
-# necessary to IGNORE the System/Random.hs files in the current directory.
-# (Otherwise instances of RandomGen are confused.)
-bench2:
-       ghc $(OPTS) -DTEST_COMPETITORS --make SimpleRNGBench.hs 
-
-clean:
-       rm -f *.o *.hi SimpleRNGBench
-#      cabal clean
-#      (cd Benchmark/ && rm -f *.o *.hi SimpleRNGBench)
-#      (cd System/    && rm -f *.o *.hi SimpleRNGBench)
diff --git a/Benchmark/RandomnessTest2.hs b/Benchmark/RandomnessTest2.hs
deleted file mode 100644 (file)
index 14bc0d7..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-module Main where
-
-import Control.Monad
-import System.Random
-
--- splitN :: (RandomGen g) => Int -> g -> ([g], g)
-splitN 0 g = ([], g)
-splitN n g = (g1:l, g')
-  where
-  (l, g') = splitN (n-1) g2
-  (g1, g2) = split g
-
--- The funny splitting operation.
-split' :: (RandomGen g) => g -> (g, g)
-split' g = (g12, g21)
-  where
-  (g1, g2) = split g
-  (_, g12) = split g1
-  (g21, _) = split g2
-
--- This test checks if generators created by calling split 2 times are independent.
--- It generates pairs of integers from 0 to n-1, using split' to
--- generate both numbers using one seed. Then it counts how often the
--- two numbers are equal.
-test :: (RandomGen g) => Int -> Int -> g -> Int
-test numTests n g = equals
-  where
-  (gs, _) = splitN numTests g
-  equals = count id $ map single gs
-  count p l = length $ filter p l
-  single g' = (fst $ randomR (0, n-1) g1) == (fst $ randomR (0, n-1) g2)
-    where
-    (g1, g2) = split' g'
-
-main = do
-  let g = mkStdGen 42
-  forM_ [2..15] $ \i -> do
-    let actual = test (i * 1000) i g
-    putStrLn $ "Generated " ++ show (i * 1000)
-      ++ " pairs of numbers from 0 to " ++ show (i - 1)
-      ++ " -- " ++ show actual ++ " pairs contained equal numbers "
-      ++ "and we expected about 1000."
diff --git a/Benchmark/RandomnessTest3.hs b/Benchmark/RandomnessTest3.hs
deleted file mode 100644 (file)
index b943f59..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-module Main where
-
-import Control.Monad
-import System.Random.TF.Gen
-import System.Random.TF.Instances
-
-splitN :: (RandomGen g) => Int -> g -> ([g], g)
-splitN 0 g = ([], g)
-splitN n g = (g1:l, g')
-  where
-  (l, g') = splitN (n-1) g2
-  (g1, g2) = split g
-
--- The funny splitting operation.
-split' :: (RandomGen g) => g -> (g, g)
-split' g = (g12, g21)
-  where
-  (g1, g2) = split g
-  (_, g12) = split g1
-  (g21, _) = split g2
-
--- This test checks if generators created by calling split 2 times are independent.
--- It generates pairs of integers from 0 to n-1, using split' to
--- generate both numbers using one seed. Then it counts how often the
--- two numbers are equal.
-test :: (RandomGen g) => Int -> Int -> g -> Int
-test numTests n g = equals
-  where
-  (gs, _) = splitN numTests g
-  equals = count id $ map single gs
-  count p l = length $ filter p l
-  single g' = (fst $ randomR (0, n-1) g1) == (fst $ randomR (0, n-1) g2)
-    where
-    (g1, g2) = split' g'
-
-main = do
-  let g = seedTFGen (42, 42, 42, 42)
-  forM_ [2..15] $ \i -> do
-    let actual = test (i * 1000) i g
-    putStrLn $ "Generated " ++ show (i * 1000)
-      ++ " pairs of numbers from 0 to " ++ show (i - 1)
-      ++ " -- " ++ show actual ++ " pairs contained equal numbers "
-      ++ "and we expected about 1000."
diff --git a/Benchmark/SimpleRNGBench.hs b/Benchmark/SimpleRNGBench.hs
deleted file mode 100644 (file)
index 04e2f77..0000000
+++ /dev/null
@@ -1,329 +0,0 @@
-{-# LANGUAGE BangPatterns, ScopedTypeVariables, ForeignFunctionInterface #-}
-{-# OPTIONS_GHC -fwarn-unused-imports #-}
-
--- | A simple script to do some very basic timing of the RNGs.
-
-module Main where
-
-import System.Exit (exitSuccess, exitFailure)
-import System.Environment
-import System.Random
-import System.CPUTime  (getCPUTime)
-import System.CPUTime.Rdtsc
-import System.Console.GetOpt
-
-import GHC.Conc
-import Control.Concurrent
-import Control.Monad 
-import Control.Exception
-
-import Data.IORef
-import Data.Word
-import Data.List hiding (last,sum)
-import Data.Int
-import Data.List.Split  hiding (split)
-import Text.Printf
-
-import Foreign.Ptr
-import Foreign.C.Types
-import Foreign.ForeignPtr
-import Foreign.Storable (peek,poke)
-
-import Prelude  hiding (last,sum)
-import BinSearch
-
-#ifdef TEST_COMPETITORS
-import System.Random.TF
-import System.Random.Mersenne.Pure64
-import System.Random.MWC
-import Control.Monad.Primitive
--- import System.IO.Unsafe
-import GHC.IO
-#endif
-
-----------------------------------------------------------------------------------------------------
--- Miscellaneous helpers:
-
--- Readable large integer printing:
-commaint :: (Show a, Integral a) => a -> String
-commaint n = 
-   reverse $ concat $
-   intersperse "," $ 
-   chunksOf 3 $ 
-   reverse (show n)
-
-padleft :: Int -> String -> String
-padleft n str | length str >= n = str
-padleft n str | otherwise       = take (n - length str) (repeat ' ') ++ str
-
-padright :: Int -> String -> String
-padright n str | length str >= n = str
-padright n str | otherwise       = str ++ take (n - length str) (repeat ' ')
-
-fmt_num :: (RealFrac a, PrintfArg a) => a -> String
-fmt_num n = if n < 100 
-           then printf "%.2f" n
-           else commaint (round n :: Integer)
-
-
--- Measure clock frequency, spinning rather than sleeping to try to
--- stay on the same core.
-measureFreq :: IO Int64
-measureFreq = do 
-  let second = 1000 * 1000 * 1000 * 1000 -- picoseconds are annoying
-  t1 <- rdtsc 
-  start <- getCPUTime
-  let loop !n !last = 
-       do t2 <- rdtsc 
-         when (t2 < last) $
-              putStrLn$ "COUNTERS WRAPPED "++ show (last,t2) 
-         cput <- getCPUTime            
-         if (cput - start < second) 
-          then loop (n+1) t2
-          else return (n,t2)
-  (n,t2) <- loop 0 t1
-  putStrLn$ "  Approx getCPUTime calls per second: "++ commaint (n::Int64)
-  when (t2 < t1) $ 
-    putStrLn$ "WARNING: rdtsc not monotonically increasing, first "++show t1++" then "++show t2++" on the same OS thread"
-
-  return$ fromIntegral (t2 - t1)
-
-----------------------------------------------------------------------------------------------------
-
--- Test overheads without actually generating any random numbers:
-data NoopRNG = NoopRNG
-instance RandomGen NoopRNG where 
-  next g     = (0,g)
-#ifdef ENABLE_SPLITTABLEGEN
-  genRange _ = (0,0)
-instance SplittableGen NoopRNG where
-#endif
-  split g = (g,g)
-
--- An RNG generating only 0 or 1:
-data BinRNG = BinRNG StdGen
-instance RandomGen BinRNG where 
-  next (BinRNG g) = (x `mod` 2, BinRNG g')
-    where (x,g') = next g
-#ifdef ENABLE_SPLITTABLEGEN
-  genRange _ = (0,1)
-instance SplittableGen BinRNG where
-#endif
-  split (BinRNG g) = (BinRNG g1, BinRNG g2)
-   where (g1,g2) = split g
-
-
-
-#ifdef TEST_COMPETITORS
-data MWCRNG = MWCRNG (Gen (PrimState IO))
--- data MWCRNG = MWCRNG GenIO
-instance RandomGen MWCRNG where 
-  -- For testing purposes we hack this to be non-monadic:
---  next g@(MWCRNG gen) = unsafePerformIO $
-  next g@(MWCRNG gen) = unsafeDupablePerformIO $
-   do v <- uniform gen
-      return (v, g)
-#endif
-
-----------------------------------------------------------------------------------------------------
--- Drivers to get random numbers repeatedly.
-
-type Kern = Int -> Ptr Int -> IO ()
-
--- [2011.01.28] Changing this to take "count" and "accumulator ptr" as arguments:
--- foreign import ccall "cbits/c_test.c" blast_rands :: Kern
--- foreign import ccall "cbits/c_test.c" store_loop  :: Kern
--- foreign import ccall unsafe "stdlib.hs" rand :: IO Int
-
-{-# INLINE timeit #-}
-timeit :: (Random a, RandomGen g) => 
-         Int -> Int64 -> String -> g -> (g -> (a,g)) -> IO ()
-timeit numthreads freq msg gen nxt =
-  do 
-     counters <- forM [1..numthreads] (const$ newIORef (1::Int64)) 
-     tids <- forM counters $ \counter -> 
-               forkIO $ infloop counter (nxt gen)   
-     threadDelay (1000*1000) -- One second
-     mapM_ killThread tids
-
-     finals <- mapM readIORef counters
-     let mean :: Double = fromIntegral (foldl1 (+) finals) / fromIntegral numthreads
-         cycles_per :: Double = fromIntegral freq / mean
-     printResult (round mean :: Int64) msg cycles_per
-
- where 
-   infloop !counter !(!_,!g) = 
-     do incr counter
-       infloop counter (nxt g)
-
-   incr !counter = 
-     do -- modifyIORef counter (+1) -- Not strict enough!
-       c <- readIORef counter
-       let c' = c+1
-       _ <- evaluate c'
-       writeIORef counter c'     
-
-
--- This function times an IO function on one or more threads.  Rather
--- than running a fixed number of iterations, it uses a binary search
--- to find out how many iterations can be completed in a second.
-timeit_foreign :: Int -> Int64 -> String -> (Int -> Ptr Int -> IO ()) -> IO Int64
-timeit_foreign numthreads freq msg ffn = do 
-  ptr     :: ForeignPtr Int <- mallocForeignPtr
-
-  let kern = if numthreads == 1
-            then ffn
-            else replicate_kernel numthreads ffn 
-      wrapped n = withForeignPtr ptr (kern$ fromIntegral n)
-  (n,t) <- binSearch False 1 (1.0, 1.05) wrapped
-
-  let total_per_second = round $ fromIntegral n * (1 / t)
-      cycles_per = fromIntegral freq * t / fromIntegral n
-  printResult total_per_second msg cycles_per
-  return total_per_second
-
- where 
-   -- This lifts a C kernel to operate simultaneously on N threads.
-   replicate_kernel :: Int -> Kern -> Kern
-   replicate_kernel nthreads kern n ptr = do
-     ptrs <- forM [1..nthreads]
-              (const mallocForeignPtr) 
-     tmpchan <- newChan
-     -- let childwork = ceiling$ fromIntegral n / fromIntegral nthreads
-     let childwork = n -- Keep it the same.. interested in per-thread throughput.
-     -- Fork/join pattern:
-     _ <- forM ptrs $ \pt -> forkIO $ 
-             withForeignPtr pt $ \p -> do
-                kern (fromIntegral childwork) p
-                result <- peek p
-                writeChan tmpchan result
-
-     results <- forM [1..nthreads] $ \_ -> 
-                 readChan tmpchan
-     -- Meaningless semantics here... sum the child ptrs and write to the input one:
-     poke ptr (foldl1 (+) results)
-     return ()
-
-
-printResult ::  Int64 -> String -> Double -> IO ()
-printResult total msg cycles_per = 
-     putStrLn$ "    "++ padleft 11 (commaint total) ++" randoms generated "++ padright 27 ("["++msg++"]") ++" ~ "
-              ++ fmt_num cycles_per ++" cycles/int"
-
-----------------------------------------------------------------------------------------------------
--- Main Script
-
-data Flag = NoC | Help 
-  deriving (Show, Eq)
-
-options :: [OptDescr Flag]
-options = 
-   [ Option ['h']  ["help"]  (NoArg Help)  "print program help"
-   , Option []     ["noC"]   (NoArg NoC)   "omit C benchmarks, haskell only"
-   ]
-
-main :: IO ()
-main = do 
-   argv <- getArgs
-   let (opts,_,other) = getOpt Permute options argv
-
-   when (not$ null other) $ do
-       putStrLn$ "ERROR: Unrecognized options: " 
-       mapM_ putStr other
-       exitFailure
-
-   when (Help `elem` opts) $ do
-       putStr$ usageInfo "Benchmark random number generation" options
-       exitSuccess
-
-   putStrLn$ "\nHow many random numbers can we generate in a second on one thread?"
-
-   t1 <- rdtsc
-   t2 <- rdtsc
-   putStrLn ("  Cost of rdtsc (ffi call):    " ++ show (t2 - t1))
-
-   freq <- measureFreq
-   putStrLn$ "  Approx clock frequency:  " ++ commaint freq
-
-   let 
-       randInt     = random :: RandomGen g => g -> (Int,g)
-       randWord16  = random :: RandomGen g => g -> (Word16,g)
-       randFloat   = random :: RandomGen g => g -> (Float,g)
-       randCFloat  = random :: RandomGen g => g -> (CFloat,g)
-       randDouble  = random :: RandomGen g => g -> (Double,g)
-       randCDouble = random :: RandomGen g => g -> (CDouble,g)
-       randInteger = random :: RandomGen g => g -> (Integer,g)
-       randBool    = random :: RandomGen g => g -> (Bool,g)
-       randChar    = random :: RandomGen g => g -> (Char,g)
-
-       gen = mkStdGen 23852358661234
-       gamut th = do
-        putStrLn$ "  First, timing System.Random.next:"
-        timeit th freq "constant zero gen"      NoopRNG next 
-        timeit th freq "System.Random stdGen/next" gen  next 
-
-        putStrLn$ "\n  Second, timing System.Random.random at different types:"
-        timeit th freq "System.Random Ints"     gen   randInt
-        timeit th freq "System.Random Word16"   gen   randWord16
-        timeit th freq "System.Random Floats"   gen   randFloat
-        timeit th freq "System.Random CFloats"  gen   randCFloat
-        timeit th freq "System.Random Doubles"  gen   randDouble
-        timeit th freq "System.Random CDoubles" gen   randCDouble
-        timeit th freq "System.Random Integers" gen   randInteger
-        timeit th freq "System.Random Bools"    gen   randBool
-        timeit th freq "System.Random Chars"    gen   randChar
-
-#ifdef TEST_COMPETITORS
-        putStrLn$ "\n  Next test other RNG packages on Hackage:"
-         let gen_mt = pureMT 39852
-             randInt2   = random :: RandomGen g => g -> (Int,g)
-            randFloat2 = random :: RandomGen g => g -> (Float,g)
-        timeit th freq "System.Random.Mersenne.Pure64 next"   gen_mt next
-        timeit th freq "System.Random.Mersenne.Pure64 Ints"   gen_mt randInt2
-        timeit th freq "System.Random.Mersenne.Pure64 Floats" gen_mt randFloat2
-
-         let gen_tf = seedTFGen (0,1,2,3)
-             randInt4   = random :: RandomGen g => g -> (Int,g)
-            randFloat4 = random :: RandomGen g => g -> (Float,g)
-         timeit th freq "System.Random.TF next" gen_tf next
-        timeit th freq "System.Random.TF Ints"   gen_tf randInt4
-        timeit th freq "System.Random.TF Floats" gen_tf randFloat4
-
-         withSystemRandom $ \ gen_mwc -> do
-           let randInt3   = random :: RandomGen g => g -> (Int,g)
-               randFloat3 = random :: RandomGen g => g -> (Float,g)
-
-           timeit th freq "System.Random.MWC next"   (MWCRNG gen_mwc) next
-           timeit th freq "System.Random.MWC Ints"   (MWCRNG gen_mwc) randInt3
-           timeit th freq "System.Random.MWC Floats" (MWCRNG gen_mwc) randFloat3
-
-#endif
-
-        putStrLn$ "\n  Next timing range-restricted System.Random.randomR:"
-        timeit th freq "System.Random Ints"     gen   (randomR (-100, 100::Int))
-        timeit th freq "System.Random Word16s"  gen   (randomR (-100, 100::Word16))
-        timeit th freq "System.Random Floats"   gen   (randomR (-100, 100::Float))
-        timeit th freq "System.Random CFloats"  gen   (randomR (-100, 100::CFloat))
-        timeit th freq "System.Random Doubles"  gen   (randomR (-100, 100::Double))
-        timeit th freq "System.Random CDoubles" gen   (randomR (-100, 100::CDouble))
-        timeit th freq "System.Random Integers" gen   (randomR (-100, 100::Integer))
-        timeit th freq "System.Random Bools"    gen   (randomR (False, True::Bool))
-        timeit th freq "System.Random Chars"    gen   (randomR ('a', 'z'))
-        timeit th freq "System.Random BIG Integers" gen (randomR (0, (2::Integer) ^ (5000::Int)))
-
-  --       when (not$ NoC `elem` opts) $ do
-  --     putStrLn$ "  Comparison to C's rand():"
-  --     timeit_foreign th freq "ptr store in C loop"   store_loop
-  --     timeit_foreign th freq "rand/store in C loop"  blast_rands
-  --     timeit_foreign th freq "rand in Haskell loop" (\n ptr -> forM_ [1..n]$ \_ -> rand )
-  --     timeit_foreign th freq "rand/store in Haskell loop"  (\n ptr -> forM_ [1..n]$ \_ -> do n <- rand; poke ptr n )
-  --     return ()
-
-   -- Test with 1 thread and numCapabilities threads:
-   gamut 1
-   when (numCapabilities > 1) $ do 
-       putStrLn$ "\nNow "++ show numCapabilities ++" threads, reporting mean randoms-per-second-per-thread:"
-       gamut numCapabilities
-       return ()
-
-   putStrLn$ "Finished."
index 15c882a..7104058 100644 (file)
@@ -1,26 +1,5 @@
-# 1.1
-  * breaking change to `randomIValInteger` to improve RNG quality and performance
-    see https://github.com/haskell/random/pull/4 and
-    ghc https://ghc.haskell.org/trac/ghc/ticket/8898
-  * correct documentation about generated range of Int32 sized values of type Int
-    https://github.com/haskell/random/pull/7
-  * fix memory leaks by using strict fields and strict atomicModifyIORef'
-    https://github.com/haskell/random/pull/8
-    related to ghc trac tickets  #7936 and #4218
-  * support for base < 4.6 (which doesnt provide strict atomicModifyIORef')
-    and integrating Travis CI support.
-    https://github.com/haskell/random/pull/12
-  * fix C type in test suite https://github.com/haskell/random/pull/9
+# Revision history for random
 
-# 1.0.1.1
-bump for overflow bug fixes
-
-# 1.0.1.2
-bump for ticket 8704, build fusion
-
-# 1.0.1.0
-bump for bug fixes,
-
-# 1.0.0.4
-bumped version for float/double range bugfix
+## 2.0.0.0  -- YYYY-mm-dd
 
+* First version. Released on an unsuspecting world.
diff --git a/DEVLOG.md b/DEVLOG.md
deleted file mode 100644 (file)
index 6e0b28d..0000000
--- a/DEVLOG.md
+++ /dev/null
@@ -1,196 +0,0 @@
-
-
-DEVLOG: A collection of notes accumulated during development.
-=============================================================
-
-
-[2011.06.24] (transient) Regression in stdGen performance.
-----------------------------------------------------------
-
-I just added a simple benchmark to make sure that whatever fix I
-introduce for trac ticket #5133 does not regress performance.  Yet in
-doing so I discovered that I'm getting much worse performance out of
-rev 130e421e912d than I'm seeing in my installed random-1.0.0.3 package.
-
-Current version:
-    How many random numbers can we generate in a second on one thread?
-      Cost of rdtsc (ffi call):    100
-      Approx getCPUTime calls per second: 234,553
-      Approx clock frequency:  3,335,220,196
-      First, timing with System.Random interface:
-        68,550,189 random ints generated [constant zero gen]         ~ 48.65 cycles/int
-           900,889 random ints generated [System.Random stdGen]      ~ 3,702 cycles/int
-
-random-1.0.0.3 version:
-    How many random numbers can we generate in a second on one thread?
-      Cost of rdtsc (ffi call):    75
-      Approx getCPUTime calls per second: 215,332
-      Approx clock frequency:  3,334,964,738
-      First, timing with System.Random interface:
-        71,683,748 random ints generated [constant zero gen]         ~ 46.52 cycles/int
-        13,609,559 random ints generated [System.Random stdGen]      ~ 245 cycles/int
-
-A >13X difference!! 
-Both are compiled with the same options.  The only difference is which
-System.Random is used.
-
-When did the regression occur?  
-
- * e059ed15172585310f9c -- 10/13/2010 perf still good
- * 6c43f80f48178ac617   -- SplittableGen introduced, still good perf
- * 130e421e912d394653a4 -- most recent, bad performance
-
-Ok... this is very odd.  It was a heisenbug becuase it's disappeared
-now!  I'll leave this note here to help remember to look for it in the
-future.
-  -Ryan
-
-
-[2011.06.24] Timing non-int types
----------------------------------
-
-The results are highly uneven:
-
-    Cost of rdtsc (ffi call):    84
-    Approx getCPUTime calls per second: 220,674
-    Approx clock frequency:  3,336,127,273
-    First, timing with System.Random interface:
-      112,976,933 randoms generated [constant zero gen]         ~ 29.53 cycles/int
-       14,415,176 randoms generated [System.Random stdGen]      ~ 231 cycles/int
-          70,751 randoms generated [System.Random Floats]      ~ 47,153 cycles/int
-          70,685 randoms generated [System.Random CFloats]     ~ 47,197 cycles/int
-       2,511,635 randoms generated [System.Random Doubles]     ~ 1,328 cycles/int
-          70,494 randoms generated [System.Random CDoubles]    ~ 47,325 cycles/int
-         858,012 randoms generated [System.Random Integers]    ~ 3,888 cycles/int
-       4,756,213 randoms generated [System.Random Bools]       ~ 701 cycles/int
-
-As you can see, all the types that use the generic randomIvalFrac /
-randomFrac definitions perform badly.  What's more, the above results
-INCLUDE an attempt to inline: 
-
-    {-# INLINE randomIvalFrac #-}
-    {-# INLINE randomFrac #-}
-    {-# INLINE randomIvalDouble #-}
-
-After reimplementing random/Float these are the new results:
-
-  Cost of rdtsc (ffi call):    100
-  Approx getCPUTime calls per second: 200,582
-  Approx clock frequency:  3,334,891,942
-  First, timing with System.Random interface:
-    105,266,949 randoms generated [constant zero gen]         ~ 31.68 cycles/int
-     13,593,392 randoms generated [System.Random stdGen]      ~ 245 cycles/int
-     10,962,597 randoms generated [System.Random Floats]      ~ 304 cycles/int
-     11,926,573 randoms generated [System.Random CFloats]     ~ 280 cycles/int
-      2,421,520 randoms generated [System.Random Doubles]     ~ 1,377 cycles/int
-      2,535,087 randoms generated [System.Random CDoubles]    ~ 1,315 cycles/int
-        856,276 randoms generated [System.Random Integers]    ~ 3,895 cycles/int
-      4,976,373 randoms generated [System.Random Bools]       ~ 670 cycles/int
-
-(But I still need to propagate these changes throughout all types / API calls.)
-
-
-
-[2011.06.28] Integer Generation via random and randomR
--------------------------------------------------------
-
-Back on the master branch I notice that while randomIvalInteger does
-well for small ranges, it's advantage doesn't scale to larger ranges:
-
-  range (-100,100):
-      5,105,290 randoms generated [System.Random Integers]    ~ 653 cycles/int
-
-  range (0,2^5000):
-          8,969 randoms generated [System.Random BIG Integers] ~ 371,848 cycles/int
-
-
-
-[2011.08.25] Validating release version 1.0.1.0 rev 40bbfd2867
---------------------------------------------------------------
-
-This is a bugfix release without SplittableGen.  It passed (cd tests;
-make test) on my Mac Os 10.6 machine.
-
-I ran GHC validate using the following fingerprint
-
-    .|c5056b932a06b4adce5167a5cb69f1f0768d28ec
-    ghc-tarballs|e7b7b152083f7c3e3559e557a239757d41ac02a6
-    libraries/Cabal|3dcc425495523ab6142027097cb598a4d2ad810a
-    libraries/Win32|085b11285b6adbc6484d9c21f5e0b8105556869c
-    libraries/array|fa295423e7404d3d1d3d82655b2b44d50f045a44
-    libraries/base|a57369f54bd25a1de5d477f3c363b3bafd17d168
-    libraries/binary|9065df2120254601c68c3a28264fd062abde9354
-    libraries/bytestring|caad22630f73e0e9b1b61f4da34f8aefcc6001d8
-    libraries/containers|667591b168c804d3eeae503dff1c848ed6852412
-    libraries/directory|d44f52926278319286804d8333149dd13d4ecc82
-    libraries/dph|b23b45a9e8fce985327b076997d61ab0ddc7b2f7
-    libraries/extensible-exceptions|e77722871a5812d52c467e3a8fd9c7b97cdec521
-    libraries/filepath|fd381017dca45de5c94dac85a6233516a6b6963d
-    libraries/ghc-prim|0a84a755e1248b4d50f6535a0ce75af0bb21b0ad
-    libraries/haskeline|8787a64417500efffc9c48032ee7c37315fb2547
-    libraries/haskell2010|470b34b6c0336339eac9fbcfb6020e46b5154bfe
-    libraries/haskell98|5590c0f042d6d07352e0bf49cedeef5ba0821f23
-    libraries/hoopl|b98db91cd0c53ddb2c275c04823f9c379774104b
-    libraries/hpc|7c726abec939b11af1ecf89740ca8d04e6a1360d
-    libraries/integer-gmp|65c73842bca2f075b65f418a5ff34753b185e0d7
-    libraries/integer-simple|10202111c59f0695ef782d1ec9e6fc992933fc9a
-    libraries/mtl|a41470c1890073e678f0dca2a9ef4c02d55bf7c6
-    libraries/old-locale|104e7e5a7b33424f34e98825a0d4ccb7614ca7c2
-    libraries/old-time|81e0c8a4b98d4b084eefe75bedf91a44edd31888
-    libraries/pretty|036fb8dfbb9d4a787fcd150c2756b4899be4e942
-    libraries/primitive|74479e07b92b8859eae473e5cc86b40decae1d6e
-    libraries/process|68ba490d6691f55eab19a249379144831055e2ac
-    libraries/random|3fb0e9e42b54d7b01b794fc27d4d678d7d74ff0e
-    libraries/template-haskell|02362d12e5ae0af20d637eec97db51f6827a1625
-    libraries/terminfo|baec6aff59d13ba294b370f9563e8068706392ce
-    libraries/unix|f55638fb5c6badd385c51a41de7ff96ef106de42
-    libraries/utf8-string|ec2b85940a256dbc8771e5e2065ca8f76cc802d0
-    libraries/vector|1e72d46bdc8488a84558b64ac63632cef1d8a695
-    libraries/xhtml|cb2cf6c34d815fdf4ed74efeb65e1993e7bda514
-    testsuite|26c608a0c31d56917099e4f48bf58c1d1e92e61c
-    utils/haddock|d54959189f33105ed09a59efee5ba34f53369282
-    utils/hsc2hs|f8cbf37ab28ab4512d932678c08c263aa412e008
-
-
-
-First validating in the context of a slightly stale GHC head
-(7.3.20110727) on a mac.
-
-
-[2011.09.30] Redoing timings after bugfix in version 1.0.1.1
-------------------------------------------------------------
-
-It looks like there has been serious performance regression (3.33ghz
-nehalem still).
-
-    How many random numbers can we generate in a second on one thread?
-      Cost of rdtsc (ffi call):    38
-      Approx getCPUTime calls per second: 7,121
-      Approx clock frequency:  96,610,524
-      First, timing System.Random.next:
-       148,133,038 randoms generated [constant zero gen]         ~ 0.65 cycles/int
-        12,656,455 randoms generated [System.Random stdGen/next] ~ 7.63 cycles/int
-
-      Second, timing System.Random.random at different types:
-           676,066 randoms generated [System.Random Ints]        ~ 143 cycles/int
-         3,917,247 randoms generated [System.Random Word16]      ~ 24.66 cycles/int
-         2,231,460 randoms generated [System.Random Floats]      ~ 43.29 cycles/int
-         2,269,993 randoms generated [System.Random CFloats]     ~ 42.56 cycles/int
-           686,363 randoms generated [System.Random Doubles]     ~ 141 cycles/int
-         2,165,679 randoms generated [System.Random CDoubles]    ~ 44.61 cycles/int
-           713,702 randoms generated [System.Random Integers]    ~ 135 cycles/int
-         3,647,551 randoms generated [System.Random Bools]       ~ 26.49 cycles/int
-         4,296,919 randoms generated [System.Random Chars]       ~ 22.48 cycles/int
-
-      Next timing range-restricted System.Random.randomR:
-         4,307,214 randoms generated [System.Random Ints]        ~ 22.43 cycles/int
-         4,068,982 randoms generated [System.Random Word16s]     ~ 23.74 cycles/int
-         2,059,264 randoms generated [System.Random Floats]      ~ 46.92 cycles/int
-         1,960,359 randoms generated [System.Random CFloats]     ~ 49.28 cycles/int
-           678,978 randoms generated [System.Random Doubles]     ~ 142 cycles/int
-         2,009,665 randoms generated [System.Random CDoubles]    ~ 48.07 cycles/int
-         4,296,452 randoms generated [System.Random Integers]    ~ 22.49 cycles/int
-         3,689,999 randoms generated [System.Random Bools]       ~ 26.18 cycles/int
-         4,367,577 randoms generated [System.Random Chars]       ~ 22.12 cycles/int
-             6,650 randoms generated [System.Random BIG Integers] ~ 14,528 cycles/int
-
diff --git a/LICENSE b/LICENSE
index 06bb641..0c53b4a 100644 (file)
--- a/LICENSE
+++ b/LICENSE
@@ -1,63 +1,26 @@
-This library (libraries/base) is derived from code from two
-sources: 
-
-  * Code from the GHC project which is largely (c) The University of
-    Glasgow, and distributable under a BSD-style license (see below),
-
-  * Code from the Haskell 98 Report which is (c) Simon Peyton Jones
-    and freely redistributable (but see the full license for
-    restrictions).
-
-The full text of these licenses is reproduced below.  Both of the
-licenses are BSD-style or compatible.
-
------------------------------------------------------------------------------
-
-The Glasgow Haskell Compiler License
-
-Copyright 2004, The University Court of the University of Glasgow. 
+Copyright (c) 2017, Carter Tazio Schonwald
 All rights reserved.
 
 Redistribution and use in source and binary forms, with or without
-modification, are permitted provided that the following conditions are met:
-
-- Redistributions of source code must retain the above copyright notice,
-this list of conditions and the following disclaimer.
-- Redistributions in binary form must reproduce the above copyright notice,
-this list of conditions and the following disclaimer in the documentation
-and/or other materials provided with the distribution.
-- Neither name of the University nor the names of its contributors may be
-used to endorse or promote products derived from this software without
-specific prior written permission. 
-
-THIS SOFTWARE IS PROVIDED BY THE UNIVERSITY COURT OF THE UNIVERSITY OF
-GLASGOW AND THE CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
-INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
-FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
-UNIVERSITY COURT OF THE UNIVERSITY OF GLASGOW OR THE CONTRIBUTORS BE LIABLE
-FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
-DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
-SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
-CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
-LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
-DAMAGE.
-
------------------------------------------------------------------------------
-
-Code derived from the document "Report on the Programming Language
-Haskell 98", is distributed under the following license:
-
-  Copyright (c) 2002 Simon Peyton Jones
-
-  The authors intend this Report to belong to the entire Haskell
-  community, and so we grant permission to copy and distribute it for
-  any purpose, provided that it is reproduced in its entirety,
-  including this Notice.  Modified versions of this Report may also be
-  copied and distributed for any purpose, provided that the modified
-  version is clearly presented as such, and that it does not claim to
-  be a definition of the Haskell 98 Language.
-
------------------------------------------------------------------------------
+modification, are permitted provided that the following conditions are
+met:
+
+1. Redistributions of source code must retain the above copyright
+   notice, this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright
+   notice, this list of conditions and the following disclaimer in the
+   documentation and/or other materials provided with the
+   distribution.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
diff --git a/README.md b/README.md
deleted file mode 100644 (file)
index 47b7589..0000000
--- a/README.md
+++ /dev/null
@@ -1,18 +0,0 @@
-The Haskell Standard Library -- Random Number Generation
-========================================================
-[![Build Status](https://secure.travis-ci.org/haskell/random.svg?branch=master)](http://travis-ci.org/haskell/random)
-
-This library provides a basic interface for (splittable) random number generators.
-
-The API documentation can be found here:
-
-   http://hackage.haskell.org/package/random/docs/System-Random.html
-
-A module supplying this interface is required for Haskell 98 (but not Haskell
-2010). An older [version]
-(https://downloads.haskell.org/~ghc/latest/docs/html/libraries/haskell98-2.0.0.3/Random.html)
-of this library is included with GHC in the haskell98 package. This newer
-version, with compatible api, is included in the [Haskell Platform]
-(http://www.haskell.org/platform/contents.html).
-
-Please report bugs in the Github [issue tracker] (https://github.com/haskell/random/issues) (no longer in the GHC trac).
index 6fa548c..9a994af 100644 (file)
--- a/Setup.hs
+++ b/Setup.hs
@@ -1,6 +1,2 @@
-module Main (main) where
-
 import Distribution.Simple
-
-main :: IO ()
 main = defaultMain
diff --git a/System/Random.hs b/System/Random.hs
deleted file mode 100644 (file)
index dfd2088..0000000
+++ /dev/null
@@ -1,609 +0,0 @@
-#if __GLASGOW_HASKELL__ >= 701
-{-# LANGUAGE Trustworthy #-}
-#endif
-
------------------------------------------------------------------------------
--- |
--- Module      :  System.Random
--- Copyright   :  (c) The University of Glasgow 2001
--- License     :  BSD-style (see the file LICENSE in the 'random' repository)
---
--- Maintainer  :  libraries@haskell.org
--- Stability   :  stable
--- Portability :  portable
---
--- This library deals with the common task of pseudo-random number
--- generation. The library makes it possible to generate repeatable
--- results, by starting with a specified initial random number generator,
--- or to get different results on each run by using the system-initialised
--- generator or by supplying a seed from some other source.
---
--- The library is split into two layers:
---
--- * A core /random number generator/ provides a supply of bits.
---   The class 'RandomGen' provides a common interface to such generators.
---   The library provides one instance of 'RandomGen', the abstract
---   data type 'StdGen'.  Programmers may, of course, supply their own
---   instances of 'RandomGen'.
---
--- * The class 'Random' provides a way to extract values of a particular
---   type from a random number generator.  For example, the 'Float'
---   instance of 'Random' allows one to generate random values of type
---   'Float'.
---
--- This implementation uses the Portable Combined Generator of L'Ecuyer
--- ["System.Random\#LEcuyer"] for 32-bit computers, transliterated by
--- Lennart Augustsson.  It has a period of roughly 2.30584e18.
---
------------------------------------------------------------------------------
-
-#include "MachDeps.h"
-
-module System.Random
-        (
-
-        -- $intro
-
-        -- * Random number generators
-
-#ifdef ENABLE_SPLITTABLEGEN
-          RandomGen(next, genRange)
-        , SplittableGen(split)
-#else
-          RandomGen(next, genRange, split)
-#endif
-        -- ** Standard random number generators
-        , StdGen
-        , mkStdGen
-
-        -- ** The global random number generator
-
-        -- $globalrng
-
-        , getStdRandom
-        , getStdGen
-        , setStdGen
-        , newStdGen
-
-        -- * Random values of various types
-        , Random ( random,   randomR,
-                   randoms,  randomRs,
-                   randomIO, randomRIO )
-
-        -- * References
-        -- $references
-
-        ) where
-
-import Prelude
-
-import Data.Bits
-import Data.Int
-import Data.Word
-import Foreign.C.Types
-
-#ifdef __NHC__
-import CPUTime          ( getCPUTime )
-import Foreign.Ptr      ( Ptr, nullPtr )
-import Foreign.C        ( CTime, CUInt )
-#else
-import System.CPUTime   ( getCPUTime )
-import Data.Time        ( getCurrentTime, UTCTime(..) )
-import Data.Ratio       ( numerator, denominator )
-#endif
-import Data.Char        ( isSpace, chr, ord )
-import System.IO.Unsafe ( unsafePerformIO )
-import Data.IORef       ( IORef, newIORef, readIORef, writeIORef )
-#if MIN_VERSION_base (4,6,0)
-import Data.IORef       ( atomicModifyIORef' )
-#else
-import Data.IORef       ( atomicModifyIORef )
-#endif
-import Numeric          ( readDec )
-
-#ifdef __GLASGOW_HASKELL__
-import GHC.Exts         ( build )
-#else
--- | A dummy variant of build without fusion.
-{-# INLINE build #-}
-build :: ((a -> [a] -> [a]) -> [a] -> [a]) -> [a]
-build g = g (:) []
-#endif
-
-#if !MIN_VERSION_base (4,6,0)
-atomicModifyIORef' :: IORef a -> (a -> (a,b)) -> IO b
-atomicModifyIORef' ref f = do
-    b <- atomicModifyIORef ref
-            (\x -> let (a, b) = f x
-                    in (a, a `seq` b))
-    b `seq` return b
-#endif
-
--- The standard nhc98 implementation of Time.ClockTime does not match
--- the extended one expected in this module, so we lash-up a quick
--- replacement here.
-#ifdef __NHC__
-foreign import ccall "time.h time" readtime :: Ptr CTime -> IO CTime
-getTime :: IO (Integer, Integer)
-getTime = do CTime t <- readtime nullPtr;  return (toInteger t, 0)
-#else
-getTime :: IO (Integer, Integer)
-getTime = do
-  utc <- getCurrentTime
-  let daytime = toRational $ utctDayTime utc
-  return $ quotRem (numerator daytime) (denominator daytime)
-#endif
-
--- | The class 'RandomGen' provides a common interface to random number
--- generators.
---
-#ifdef ENABLE_SPLITTABLEGEN
--- Minimal complete definition: 'next'.
-#else
--- Minimal complete definition: 'next' and 'split'.
-#endif
-
-class RandomGen g where
-
-   -- |The 'next' operation returns an 'Int' that is uniformly distributed
-   -- in the range returned by 'genRange' (including both end points),
-   -- and a new generator.
-   next     :: g -> (Int, g)
-
-   -- |The 'genRange' operation yields the range of values returned by
-   -- the generator.
-   --
-   -- It is required that:
-   --
-   -- * If @(a,b) = 'genRange' g@, then @a < b@.
-   --
-   -- * 'genRange' always returns a pair of defined 'Int's.
-   --
-   -- The second condition ensures that 'genRange' cannot examine its
-   -- argument, and hence the value it returns can be determined only by the
-   -- instance of 'RandomGen'.  That in turn allows an implementation to make
-   -- a single call to 'genRange' to establish a generator's range, without
-   -- being concerned that the generator returned by (say) 'next' might have
-   -- a different range to the generator passed to 'next'.
-   --
-   -- The default definition spans the full range of 'Int'.
-   genRange :: g -> (Int,Int)
-
-   -- default method
-   genRange _ = (minBound, maxBound)
-
-#ifdef ENABLE_SPLITTABLEGEN
--- | The class 'SplittableGen' proivides a way to specify a random number
---   generator that can be split into two new generators.
-class SplittableGen g where
-#endif
-   -- |The 'split' operation allows one to obtain two distinct random number
-   -- generators. This is very useful in functional programs (for example, when
-   -- passing a random number generator down to recursive calls), but very
-   -- little work has been done on statistically robust implementations of
-   -- 'split' (["System.Random\#Burton", "System.Random\#Hellekalek"]
-   -- are the only examples we know of).
-   split    :: g -> (g, g)
-
-{- |
-The 'StdGen' instance of 'RandomGen' has a 'genRange' of at least 30 bits.
-
-The result of repeatedly using 'next' should be at least as statistically
-robust as the /Minimal Standard Random Number Generator/ described by
-["System.Random\#Park", "System.Random\#Carta"].
-Until more is known about implementations of 'split', all we require is
-that 'split' deliver generators that are (a) not identical and
-(b) independently robust in the sense just given.
-
-The 'Show' and 'Read' instances of 'StdGen' provide a primitive way to save the
-state of a random number generator.
-It is required that @'read' ('show' g) == g@.
-
-In addition, 'reads' may be used to map an arbitrary string (not necessarily one
-produced by 'show') onto a value of type 'StdGen'. In general, the 'Read'
-instance of 'StdGen' has the following properties:
-
-* It guarantees to succeed on any string.
-
-* It guarantees to consume only a finite portion of the string.
-
-* Different argument strings are likely to result in different results.
-
--}
-
-data StdGen
- = StdGen !Int32 !Int32
-
-instance RandomGen StdGen where
-  next  = stdNext
-  genRange _ = stdRange
-
-#ifdef ENABLE_SPLITTABLEGEN
-instance SplittableGen StdGen where
-#endif
-  split = stdSplit
-
-instance Show StdGen where
-  showsPrec p (StdGen s1 s2) =
-     showsPrec p s1 .
-     showChar ' ' .
-     showsPrec p s2
-
-instance Read StdGen where
-  readsPrec _p = \ r ->
-     case try_read r of
-       r'@[_] -> r'
-       _   -> [stdFromString r] -- because it shouldn't ever fail.
-    where
-      try_read r = do
-         (s1, r1) <- readDec (dropWhile isSpace r)
-         (s2, r2) <- readDec (dropWhile isSpace r1)
-         return (StdGen s1 s2, r2)
-
-{-
- If we cannot unravel the StdGen from a string, create
- one based on the string given.
--}
-stdFromString         :: String -> (StdGen, String)
-stdFromString s        = (mkStdGen num, rest)
-        where (cs, rest) = splitAt 6 s
-              num        = foldl (\a x -> x + 3 * a) 1 (map ord cs)
-
-
-{- |
-The function 'mkStdGen' provides an alternative way of producing an initial
-generator, by mapping an 'Int' into a generator. Again, distinct arguments
-should be likely to produce distinct generators.
--}
-mkStdGen :: Int -> StdGen -- why not Integer ?
-mkStdGen s = mkStdGen32 $ fromIntegral s
-
-{-
-From ["System.Random\#LEcuyer"]: "The integer variables s1 and s2 ... must be
-initialized to values in the range [1, 2147483562] and [1, 2147483398]
-respectively."
--}
-mkStdGen32 :: Int32 -> StdGen
-mkStdGen32 sMaybeNegative = StdGen (s1+1) (s2+1)
-      where
-        -- We want a non-negative number, but we can't just take the abs
-        -- of sMaybeNegative as -minBound == minBound.
-        s       = sMaybeNegative .&. maxBound
-        (q, s1) = s `divMod` 2147483562
-        s2      = q `mod` 2147483398
-
-createStdGen :: Integer -> StdGen
-createStdGen s = mkStdGen32 $ fromIntegral s
-
-{- |
-With a source of random number supply in hand, the 'Random' class allows the
-programmer to extract random values of a variety of types.
-
-Minimal complete definition: 'randomR' and 'random'.
-
--}
-
-class Random a where
-  -- | Takes a range /(lo,hi)/ and a random number generator
-  -- /g/, and returns a random value uniformly distributed in the closed
-  -- interval /[lo,hi]/, together with a new generator. It is unspecified
-  -- what happens if /lo>hi/. For continuous types there is no requirement
-  -- that the values /lo/ and /hi/ are ever produced, but they may be,
-  -- depending on the implementation and the interval.
-  randomR :: RandomGen g => (a,a) -> g -> (a,g)
-
-  -- | The same as 'randomR', but using a default range determined by the type:
-  --
-  -- * For bounded types (instances of 'Bounded', such as 'Char'),
-  --   the range is normally the whole type.
-  --
-  -- * For fractional types, the range is normally the semi-closed interval
-  -- @[0,1)@.
-  --
-  -- * For 'Integer', the range is (arbitrarily) the range of 'Int'.
-  random  :: RandomGen g => g -> (a, g)
-
-  -- | Plural variant of 'randomR', producing an infinite list of
-  -- random values instead of returning a new generator.
-  {-# INLINE randomRs #-}
-  randomRs :: RandomGen g => (a,a) -> g -> [a]
-  randomRs ival g = build (\cons _nil -> buildRandoms cons (randomR ival) g)
-
-  -- | Plural variant of 'random', producing an infinite list of
-  -- random values instead of returning a new generator.
-  {-# INLINE randoms #-}
-  randoms  :: RandomGen g => g -> [a]
-  randoms  g      = build (\cons _nil -> buildRandoms cons random g)
-
-  -- | A variant of 'randomR' that uses the global random number generator
-  -- (see "System.Random#globalrng").
-  randomRIO :: (a,a) -> IO a
-  randomRIO range  = getStdRandom (randomR range)
-
-  -- | A variant of 'random' that uses the global random number generator
-  -- (see "System.Random#globalrng").
-  randomIO  :: IO a
-  randomIO         = getStdRandom random
-
--- | Produce an infinite list-equivalent of random values.
-{-# INLINE buildRandoms #-}
-buildRandoms :: RandomGen g
-             => (a -> as -> as)  -- ^ E.g. '(:)' but subject to fusion
-             -> (g -> (a,g))     -- ^ E.g. 'random'
-             -> g                -- ^ A 'RandomGen' instance
-             -> as
-buildRandoms cons rand = go
-  where
-    -- The seq fixes part of #4218 and also makes fused Core simpler.
-    go g = x `seq` (x `cons` go g') where (x,g') = rand g
-
-
-instance Random Integer where
-  randomR ival g = randomIvalInteger ival g
-  random g       = randomR (toInteger (minBound::Int), toInteger (maxBound::Int)) g
-
-instance Random Int        where randomR = randomIvalIntegral; random = randomBounded
-instance Random Int8       where randomR = randomIvalIntegral; random = randomBounded
-instance Random Int16      where randomR = randomIvalIntegral; random = randomBounded
-instance Random Int32      where randomR = randomIvalIntegral; random = randomBounded
-instance Random Int64      where randomR = randomIvalIntegral; random = randomBounded
-
-#ifndef __NHC__
--- Word is a type synonym in nhc98.
-instance Random Word       where randomR = randomIvalIntegral; random = randomBounded
-#endif
-instance Random Word8      where randomR = randomIvalIntegral; random = randomBounded
-instance Random Word16     where randomR = randomIvalIntegral; random = randomBounded
-instance Random Word32     where randomR = randomIvalIntegral; random = randomBounded
-instance Random Word64     where randomR = randomIvalIntegral; random = randomBounded
-
-instance Random CChar      where randomR = randomIvalIntegral; random = randomBounded
-instance Random CSChar     where randomR = randomIvalIntegral; random = randomBounded
-instance Random CUChar     where randomR = randomIvalIntegral; random = randomBounded
-instance Random CShort     where randomR = randomIvalIntegral; random = randomBounded
-instance Random CUShort    where randomR = randomIvalIntegral; random = randomBounded
-instance Random CInt       where randomR = randomIvalIntegral; random = randomBounded
-instance Random CUInt      where randomR = randomIvalIntegral; random = randomBounded
-instance Random CLong      where randomR = randomIvalIntegral; random = randomBounded
-instance Random CULong     where randomR = randomIvalIntegral; random = randomBounded
-instance Random CPtrdiff   where randomR = randomIvalIntegral; random = randomBounded
-instance Random CSize      where randomR = randomIvalIntegral; random = randomBounded
-instance Random CWchar     where randomR = randomIvalIntegral; random = randomBounded
-instance Random CSigAtomic where randomR = randomIvalIntegral; random = randomBounded
-instance Random CLLong     where randomR = randomIvalIntegral; random = randomBounded
-instance Random CULLong    where randomR = randomIvalIntegral; random = randomBounded
-instance Random CIntPtr    where randomR = randomIvalIntegral; random = randomBounded
-instance Random CUIntPtr   where randomR = randomIvalIntegral; random = randomBounded
-instance Random CIntMax    where randomR = randomIvalIntegral; random = randomBounded
-instance Random CUIntMax   where randomR = randomIvalIntegral; random = randomBounded
-
-instance Random Char where
-  randomR (a,b) g =
-       case (randomIvalInteger (toInteger (ord a), toInteger (ord b)) g) of
-         (x,g') -> (chr x, g')
-  random g        = randomR (minBound,maxBound) g
-
-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
-
-{-# INLINE randomRFloating #-}
-randomRFloating :: (Fractional a, Num a, Ord a, Random a, RandomGen g) => (a, a) -> g -> (a, g)
-randomRFloating (l,h) g
-    | l>h       = randomRFloating (h,l) g
-    | otherwise = let (coef,g') = random g in
-                  (2.0 * (0.5*l + coef * (0.5*h - 0.5*l)), g')  -- avoid overflow
-
-instance Random Double where
-  randomR = randomRFloating
-  random rng     =
-    case random rng of
-      (x,rng') ->
-          -- We use 53 bits of randomness corresponding to the 53 bit significand:
-          ((fromIntegral (mask53 .&. (x::Int64)) :: Double)
-           /  fromIntegral twoto53, rng')
-   where
-    twoto53 = (2::Int64) ^ (53::Int64)
-    mask53 = twoto53 - 1
-
-instance Random Float where
-  randomR = randomRFloating
-  random rng =
-    -- TODO: Faster to just use 'next' IF it generates enough bits of randomness.
-    case random rng of
-      (x,rng') ->
-          -- We use 24 bits of randomness corresponding to the 24 bit significand:
-          ((fromIntegral (mask24 .&. (x::Int32)) :: Float)
-           /  fromIntegral twoto24, rng')
-         -- Note, encodeFloat is another option, but I'm not seeing slightly
-         --  worse performance with the following [2011.06.25]:
---         (encodeFloat rand (-24), rng')
-   where
-     mask24 = twoto24 - 1
-     twoto24 = (2::Int32) ^ (24::Int32)
-
--- CFloat/CDouble are basically the same as a Float/Double:
-instance Random CFloat where
-  randomR = randomRFloating
-  random rng = case random rng of
-                 (x,rng') -> (realToFrac (x::Float), rng')
-
-instance Random CDouble where
-  randomR = randomRFloating
-  -- A MYSTERY:
-  -- Presently, this is showing better performance than the Double instance:
-  -- (And yet, if the Double instance uses randomFrac then its performance is much worse!)
-  random  = randomFrac
-  -- random rng = case random rng of
-  --             (x,rng') -> (realToFrac (x::Double), rng')
-
-mkStdRNG :: Integer -> IO StdGen
-mkStdRNG o = do
-    ct          <- getCPUTime
-    (sec, psec) <- getTime
-    return (createStdGen (sec * 12345 + psec + ct + o))
-
-randomBounded :: (RandomGen g, Random a, Bounded a) => g -> (a, g)
-randomBounded = randomR (minBound, maxBound)
-
--- The two integer functions below take an [inclusive,inclusive] range.
-randomIvalIntegral :: (RandomGen g, Integral a) => (a, a) -> g -> (a, g)
-randomIvalIntegral (l,h) = randomIvalInteger (toInteger l, toInteger h)
-
-{-# SPECIALIZE randomIvalInteger :: (Num a) =>
-    (Integer, Integer) -> StdGen -> (a, StdGen) #-}
-
-randomIvalInteger :: (RandomGen g, Num a) => (Integer, Integer) -> g -> (a, g)
-randomIvalInteger (l,h) rng
- | l > h     = randomIvalInteger (h,l) rng
- | otherwise = case (f 1 0 rng) of (v, rng') -> (fromInteger (l + v `mod` k), rng')
-     where
-       (genlo, genhi) = genRange rng
-       b = fromIntegral genhi - fromIntegral genlo + 1
-
-       -- Probabilities of the most likely and least likely result
-       -- will differ at most by a factor of (1 +- 1/q).  Assuming the RandomGen
-       -- is uniform, of course
-
-       -- On average, log q / log b more random values will be generated
-       -- than the minimum
-       q = 1000
-       k = h - l + 1
-       magtgt = k * q
-
-       -- generate random values until we exceed the target magnitude
-       f mag v g | mag >= magtgt = (v, g)
-                 | otherwise = v' `seq`f (mag*b) v' g' where
-                        (x,g') = next g
-                        v' = (v * b + (fromIntegral x - fromIntegral genlo))
-
-
--- The continuous functions on the other hand take an [inclusive,exclusive) range.
-randomFrac :: (RandomGen g, Fractional a) => g -> (a, g)
-randomFrac = randomIvalDouble (0::Double,1) realToFrac
-
-randomIvalDouble :: (RandomGen g, Fractional a) => (Double, Double) -> (Double -> a) -> g -> (a, g)
-randomIvalDouble (l,h) fromDouble rng
-  | l > h     = randomIvalDouble (h,l) fromDouble rng
-  | otherwise =
-       case (randomIvalInteger (toInteger (minBound::Int32), toInteger (maxBound::Int32)) rng) of
-         (x, rng') ->
-            let
-             scaled_x =
-                fromDouble (0.5*l + 0.5*h) +                   -- previously (l+h)/2, overflowed
-                fromDouble ((0.5*h - 0.5*l) / (0.5 * realToFrac int32Count)) *  -- avoid overflow
-                fromIntegral (x::Int32)
-            in
-            (scaled_x, rng')
-
-int32Count :: Integer
-int32Count = toInteger (maxBound::Int32) - toInteger (minBound::Int32) + 1  -- GHC ticket #3982
-
-stdRange :: (Int,Int)
-stdRange = (1, 2147483562)
-
-stdNext :: StdGen -> (Int, StdGen)
--- Returns values in the range stdRange
-stdNext (StdGen s1 s2) = (fromIntegral z', StdGen s1'' s2'')
-        where   z'   = if z < 1 then z + 2147483562 else z
-                z    = s1'' - s2''
-
-                k    = s1 `quot` 53668
-                s1'  = 40014 * (s1 - k * 53668) - k * 12211
-                s1'' = if s1' < 0 then s1' + 2147483563 else s1'
-
-                k'   = s2 `quot` 52774
-                s2'  = 40692 * (s2 - k' * 52774) - k' * 3791
-                s2'' = if s2' < 0 then s2' + 2147483399 else s2'
-
-stdSplit            :: StdGen -> (StdGen, StdGen)
-stdSplit std@(StdGen s1 s2)
-                     = (left, right)
-                       where
-                        -- no statistical foundation for this!
-                        left    = StdGen new_s1 t2
-                        right   = StdGen t1 new_s2
-
-                        new_s1 | s1 == 2147483562 = 1
-                               | otherwise        = s1 + 1
-
-                        new_s2 | s2 == 1          = 2147483398
-                               | otherwise        = s2 - 1
-
-                        StdGen t1 t2 = snd (next std)
-
--- The global random number generator
-
-{- $globalrng #globalrng#
-
-There is a single, implicit, global random number generator of type
-'StdGen', held in some global variable maintained by the 'IO' monad. It is
-initialised automatically in some system-dependent fashion, for example, by
-using the time of day, or Linux's kernel random number generator. To get
-deterministic behaviour, use 'setStdGen'.
--}
-
--- |Sets the global random number generator.
-setStdGen :: StdGen -> IO ()
-setStdGen sgen = writeIORef theStdGen sgen
-
--- |Gets the global random number generator.
-getStdGen :: IO StdGen
-getStdGen  = readIORef theStdGen
-
-theStdGen :: IORef StdGen
-theStdGen  = unsafePerformIO $ do
-   rng <- mkStdRNG 0
-   newIORef rng
-
--- |Applies 'split' to the current global random generator,
--- updates it with one of the results, and returns the other.
-newStdGen :: IO StdGen
-newStdGen = atomicModifyIORef' theStdGen split
-
-{- |Uses the supplied function to get a value from the current global
-random generator, and updates the global generator with the new generator
-returned by the function. For example, @rollDice@ gets a random integer
-between 1 and 6:
-
->  rollDice :: IO Int
->  rollDice = getStdRandom (randomR (1,6))
-
--}
-
-getStdRandom :: (StdGen -> (a,StdGen)) -> IO a
-getStdRandom f = atomicModifyIORef' theStdGen (swap . f)
-  where swap (v,g) = (g,v)
-
-{- $references
-
-1. FW #Burton# Burton and RL Page, /Distributed random number generation/,
-Journal of Functional Programming, 2(2):203-212, April 1992.
-
-2. SK #Park# Park, and KW Miller, /Random number generators -
-good ones are hard to find/, Comm ACM 31(10), Oct 1988, pp1192-1201.
-
-3. DG #Carta# Carta, /Two fast implementations of the minimal standard
-random number generator/, Comm ACM, 33(1), Jan 1990, pp87-88.
-
-4. P #Hellekalek# Hellekalek, /Don\'t trust parallel Monte Carlo/,
-Department of Mathematics, University of Salzburg,
-<http://random.mat.sbg.ac.at/~peter/pads98.ps>, 1998.
-
-5. Pierre #LEcuyer# L'Ecuyer, /Efficient and portable combined random
-number generators/, Comm ACM, 31(6), Jun 1988, pp742-749.
-
-The Web site <http://random.mat.sbg.ac.at/> is a great source of information.
-
--}
diff --git a/prologue.txt b/prologue.txt
deleted file mode 100644 (file)
index ea0344b..0000000
+++ /dev/null
@@ -1 +0,0 @@
-Random number library.
index a28063c..ac22c68 100644 (file)
@@ -1,70 +1,70 @@
-name:          random
-version:       1.1
-
-
-
-
-license:       BSD3
-license-file:  LICENSE
-maintainer:    core-libraries-committee@haskell.org
-bug-reports:   https://github.com/haskell/random/issues
-synopsis:      random number library
-category:       System
-description:
-       This package provides a basic random number generation
-       library, including the ability to split random number
-       generators.
-
-extra-source-files:
-  .travis.yml
-  README.md
-  CHANGELOG.md
-  .gitignore
-  .darcs-boring
-
-
-
-build-type: Simple
--- cabal-version 1.8 needed because "the field 'build-depends: random' refers
--- to a library which is defined within the same package"
-cabal-version: >= 1.8
-
-
-
-Library
-    exposed-modules:
-        System.Random
-    extensions:        CPP
-    GHC-Options: -O2
-    build-depends: base >= 3 && < 5, time
-
-source-repository head
-    type:     git
-    location: https://github.com/haskell/random.git
-
--- To run the Test-Suite:
--- $ cabal configure --enable-tests
--- $ cabal test --show-details=always --test-options="+RTS -M1M -RTS"
-
-Test-Suite T7936
-    type:           exitcode-stdio-1.0
-    main-is:        T7936.hs
-    hs-source-dirs: tests
-    build-depends:  base >= 3 && < 5, random
-    ghc-options:    -rtsopts -O2
-
-Test-Suite TestRandomRs
-    type:           exitcode-stdio-1.0
-    main-is:        TestRandomRs.hs
-    hs-source-dirs: tests
-    build-depends:  base >= 3 && < 5, random
-    ghc-options:    -rtsopts -O2
-    -- TODO. Why does the following not work?
-    --test-options:   +RTS -M1M -RTS
-
-Test-Suite TestRandomIOs
-    type:           exitcode-stdio-1.0
-    main-is:        TestRandomIOs.hs
-    hs-source-dirs: tests
-    build-depends:  base >= 3 && < 5, random
-    ghc-options:    -rtsopts -O2
+-- Initial random.cabal generated by cabal init.  For further 
+-- documentation, see http://haskell.org/cabal/users-guide/
+
+-- The name of the package.
+name:                random
+
+-- The package version.  See the Haskell package versioning policy (PVP) 
+-- for standards guiding when and how versions should be incremented.
+-- https://wiki.haskell.org/Package_versioning_policy
+-- PVP summary:      +-+------- breaking API changes
+--                   | | +----- non-breaking API additions
+--                   | | | +--- code changes with no API change
+version:             2.0.0.0
+
+-- A short (one-line) description of the package.
+synopsis:            Random number generation library for haskell
+
+-- A longer description of the package.
+-- description:         
+
+-- URL for the project homepage or repository.
+homepage:            http://github.com/cartazio/random
+
+-- The license under which the package is released.
+license:             BSD2
+
+-- The file containing the license text.
+license-file:        LICENSE
+
+-- The package author(s).
+author:              Carter Tazio Schonwald
+
+-- An email address to which users can send suggestions, bug reports, and 
+-- patches.
+maintainer:          carter at wellposed dot com
+
+-- A copyright notice.
+-- copyright:           
+
+category:            Math
+
+build-type:          Simple
+
+-- Extra files to be distributed with the package, such as examples or a 
+-- README.
+extra-source-files:  ChangeLog.md
+
+-- Constraint on the version of Cabal needed to build this package.
+cabal-version:       >=1.10
+
+
+library
+  -- Modules exported by the library.
+  -- exposed-modules:     
+  
+  -- Modules included in this library but not exported.
+  -- other-modules:       
+  
+  -- LANGUAGE extensions used by modules in this package.
+  -- other-extensions:    
+  
+  -- Other library packages from which modules are imported.
+  build-depends:       base >=4.9 && <4.10
+  
+  -- Directories containing source files.
+  hs-source-dirs:      src
+  
+  -- Base language which the package is written in.
+  default-language:    Haskell2010
+  
diff --git a/tests/Makefile b/tests/Makefile
deleted file mode 100644 (file)
index 39c7149..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-# This Makefile runs the tests using GHC's testsuite framework.  It
-# assumes the package is part of a GHC build tree with the testsuite
-# installed in ../../../testsuite.
-
-TOP=../../../testsuite
-include $(TOP)/mk/boilerplate.mk
-include $(TOP)/mk/test.mk
-
-
-# Build tests locally without the central GHC testing infrastructure:
-local:
-       ghc --make rangeTest.hs
-       ghc --make random1283.hs
-
diff --git a/tests/T7936.hs b/tests/T7936.hs
deleted file mode 100644 (file)
index cfea911..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
--- Test for ticket #7936:
--- https://ghc.haskell.org/trac/ghc/ticket/7936
---
--- Used to fail with:
---
--- $ cabal test T7936 --test-options="+RTS -M1M -RTS"
--- T7936: Heap exhausted;
-
-module Main where
-
-import System.Random (newStdGen)
-import Control.Monad (replicateM_)
-
-main = replicateM_ 100000 newStdGen
diff --git a/tests/TestRandomIOs.hs b/tests/TestRandomIOs.hs
deleted file mode 100644 (file)
index d8a00cc..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
--- Test for ticket #4218 (TestRandomIOs):
--- https://ghc.haskell.org/trac/ghc/ticket/4218
---
--- Used to fail with:
---
--- $ cabal test TestRandomIOs --test-options="+RTS -M1M -RTS"
--- TestRandomIOs: Heap exhausted;
-
-module Main where
-
-import Control.Monad (replicateM)
-import System.Random (randomIO)
-
--- Build a list of 5000 random ints in memory (IO Monad is strict), and print
--- the last one.
--- Should use less than 1Mb of heap space, or we are generating a list of
--- unevaluated thunks.
-main = do
-    rs <- replicateM 5000 randomIO :: IO [Int]
-    print $ last rs
diff --git a/tests/TestRandomRs.hs b/tests/TestRandomRs.hs
deleted file mode 100644 (file)
index cdae106..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
--- Test for ticket #4218 (TestRandomRs):
--- https://ghc.haskell.org/trac/ghc/ticket/4218
---
--- Fixed together with ticket #8704
--- https://ghc.haskell.org/trac/ghc/ticket/8704
--- Commit 4695ffa366f659940369f05e419a4f2249c3a776
---
--- Used to fail with:
---
--- $ cabal test TestRandomRs --test-options="+RTS -M1M -RTS"
--- TestRandomRs: Heap exhausted;
-
-module Main where
-
-import Control.Monad (liftM, replicateM)
-import System.Random (randomRs, getStdGen)
-
--- Return the five-thousandth random number:
--- Should run in constant space (< 1Mb heap).
-main = do
-    n <- (last . take 5000 . randomRs (0, 1000000)) `liftM` getStdGen
-    print (n::Integer)
diff --git a/tests/all.T b/tests/all.T
deleted file mode 100644 (file)
index f85ec76..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-setTestOpts(reqlib('random'))
-
-test('rangeTest',
-     normal,
-     compile_and_run,
-     [''])
-
-test('random1283',
-     reqlib('containers'),
-     compile_and_run,
-     [' -package containers'])
diff --git a/tests/random1283.hs b/tests/random1283.hs
deleted file mode 100644 (file)
index 33fc488..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-import Control.Concurrent
-import Control.Monad hiding (empty)
-import Data.Sequence (ViewL(..), empty, fromList, viewl, (<|), (|>), (><))
-import System.Random
-
--- This test
-
-threads = 4
-samples = 5000
-
-main = loopTest threads samples
-
-loopTest t s = do
-  isClean <- testRace t s
-  when (not isClean) $ putStrLn "race condition!"
-
-testRace t s = do
-  ref <- liftM (take (t*s) . randoms) getStdGen
-  iss <- threadRandoms t s
-  return (isInterleavingOf (ref::[Int]) iss)
-
-threadRandoms :: Random a => Int -> Int -> IO [[a]]
-threadRandoms t s = do
-  vs <- sequence $ replicate t $ do
-    v <- newEmptyMVar
-    forkIO (sequence (replicate s randomIO) >>= putMVar v)
-    return v
-  mapM takeMVar vs
-
-isInterleavingOf xs yss = iio xs (viewl $ fromList yss) EmptyL where
-  iio (x:xs) ((y:ys) :< yss) zss
-    | x /= y = iio (x:xs) (viewl yss) (viewl (fromViewL zss |> (y:ys)))
-    | x == y = iio xs (viewl ((ys <| yss) >< fromViewL zss)) EmptyL
-  iio xs ([] :< yss) zss = iio xs (viewl yss) zss
-  iio [] EmptyL EmptyL = True
-  iio _ _ _ = False
-
-fromViewL (EmptyL) = empty
-fromViewL (x :< xs) = x <| xs
-
diff --git a/tests/rangeTest.hs b/tests/rangeTest.hs
deleted file mode 100644 (file)
index ac62c71..0000000
+++ /dev/null
@@ -1,135 +0,0 @@
-{-# LANGUAGE CPP #-}
-import Control.Monad
-import System.Random
-import Data.Int
-import Data.Word
-import Data.Bits
-import Foreign.C.Types
-
--- Take many measurements and record the max/min/average random values.
-approxBounds :: (RandomGen g, Random a, Ord a, Num a) => 
-               (g -> (a,g)) -> Int -> a -> (a,a) -> g -> ((a,a,a),g)
--- Here we do a little hack to essentiall pass in the type in the last argument:
-approxBounds nxt iters unused (explo,exphi) initrng = 
-   if False 
-   then ((unused,unused,unused),undefined)
---   else loop initrng iters 100 (-100) 0 -- Oops, can't use minBound/maxBound here.
-   else loop initrng iters exphi explo 0 -- Oops, can't use minBound/maxBound here.
- where 
-  loop rng 0 mn mx sum = ((mn,mx,sum),rng)
-  loop rng  n mn mx sum = 
-    case nxt rng of 
-      (x, rng') -> loop rng' (n-1) (min x mn) (max x mx) (x+sum)
-
-
--- We check that:
---     (1) all generated numbers are in bounds
---     (2) we get "close" to the bounds
--- The with (2) is that we do enough trials to ensure that we can at
--- least hit the 90% mark.
-checkBounds:: (Real a, Show a, Ord a) =>
-             String -> (Bool, a, a) -> ((a,a) -> StdGen -> ((a, a, t), StdGen)) -> IO ()
-checkBounds msg (exclusive,lo,hi) fun = 
- -- (lo,hi) is [inclusive,exclusive) 
- do putStr$ msg 
---         ++ ", expected range " ++ show (lo,hi) 
-           ++ ":  "
-    (mn,mx,sum) <- getStdRandom (fun (lo,hi))
-    when (mn <  lo)$ error$ "broke lower bound: " ++ show mn
-    when (mx > hi) $ error$ "broke upper bound: " ++ show mx
-    when (exclusive && mx >= hi)$ error$ "hit upper bound: " ++ show mx
-
-    let epsilon = 0.1 * (toRational hi - toRational lo)
-
-    when (toRational (hi - mx) > epsilon)$ error$ "didn't get close enough to upper bound: "++ show mx
-    when (toRational (mn - lo) > epsilon)$ error$ "didn't get close enough to lower bound: "++ show mn
-    putStrLn "Passed" 
-
-boundedRange :: (Num a, Bounded a) => (Bool, a, a)
-boundedRange  = ( False, minBound, maxBound )
-
-trials = 5000
-
--- Keep in mind here that on some architectures (e.g. ARM) CChar, CWchar, and CSigAtomic
--- are unsigned
-
-main = 
- do 
-    checkBounds "Int"     boundedRange   (approxBounds random trials (undefined::Int))
-    checkBounds "Integer" (False, fromIntegral (minBound::Int), fromIntegral (maxBound::Int))
-                                         (approxBounds random trials (undefined::Integer))
-    checkBounds "Int8"    boundedRange   (approxBounds random trials (undefined::Int8))
-    checkBounds "Int16"   boundedRange   (approxBounds random trials (undefined::Int16))
-    checkBounds "Int32"   boundedRange   (approxBounds random trials (undefined::Int32))
-    checkBounds "Int64"   boundedRange   (approxBounds random trials (undefined::Int64))
-    checkBounds "Word"    boundedRange   (approxBounds random trials (undefined::Word))
-    checkBounds "Word8"   boundedRange   (approxBounds random trials (undefined::Word8))
-    checkBounds "Word16"  boundedRange   (approxBounds random trials (undefined::Word16))
-    checkBounds "Word32"  boundedRange   (approxBounds random trials (undefined::Word32))
-    checkBounds "Word64"  boundedRange   (approxBounds random trials (undefined::Word64))
-    checkBounds "Double"  (True,0.0,1.0) (approxBounds random trials (undefined::Double))
-    checkBounds "Float"   (True,0.0,1.0) (approxBounds random trials (undefined::Float))
-
-    checkBounds "CChar"      boundedRange (approxBounds random trials (undefined:: CChar))
-    checkBounds "CSChar"     boundedRange (approxBounds random trials (undefined:: CSChar))
-    checkBounds "CUChar"     boundedRange (approxBounds random trials (undefined:: CUChar))
-    checkBounds "CShort"     boundedRange (approxBounds random trials (undefined:: CShort))
-    checkBounds "CUShort"    boundedRange (approxBounds random trials (undefined:: CUShort))
-    checkBounds "CInt"       boundedRange (approxBounds random trials (undefined:: CInt))
-    checkBounds "CUInt"      boundedRange (approxBounds random trials (undefined:: CUInt))
-    checkBounds "CLong"      boundedRange (approxBounds random trials (undefined:: CLong))
-    checkBounds "CULong"     boundedRange (approxBounds random trials (undefined:: CULong))
-    checkBounds "CPtrdiff"   boundedRange (approxBounds random trials (undefined:: CPtrdiff))
-    checkBounds "CSize"      boundedRange (approxBounds random trials (undefined:: CSize))
-    checkBounds "CWchar"     boundedRange (approxBounds random trials (undefined:: CWchar))
-    checkBounds "CSigAtomic" boundedRange (approxBounds random trials (undefined:: CSigAtomic))
-    checkBounds "CLLong"     boundedRange (approxBounds random trials (undefined:: CLLong))
-    checkBounds "CULLong"    boundedRange (approxBounds random trials (undefined:: CULLong))
-    checkBounds "CIntPtr"    boundedRange (approxBounds random trials (undefined:: CIntPtr))
-    checkBounds "CUIntPtr"   boundedRange (approxBounds random trials (undefined:: CUIntPtr))
-    checkBounds "CIntMax"    boundedRange (approxBounds random trials (undefined:: CIntMax))
-    checkBounds "CUIntMax"   boundedRange (approxBounds random trials (undefined:: CUIntMax))
-
-  -- Then check all the range-restricted versions:
-    checkBounds "Int R"     (False,-100,100)  (approxBounds (randomR (-100,100)) trials (undefined::Int))
-    checkBounds "Integer R" (False,-100,100)  (approxBounds (randomR (-100,100)) trials (undefined::Integer))
-    checkBounds "Int8 R"    (False,-100,100)  (approxBounds (randomR (-100,100)) trials (undefined::Int8))
-    checkBounds "Int8 Rsmall" (False,-50,50)  (approxBounds (randomR (-50,50))   trials (undefined::Int8))
-    checkBounds "Int8 Rmini"    (False,3,4)   (approxBounds (randomR (3,4))      trials (undefined::Int8))
-    checkBounds "Int8 Rtrivial" (False,3,3)   (approxBounds (randomR (3,3))      trials (undefined::Int8))
-
-    checkBounds "Int16 R"   (False,-100,100)  (approxBounds (randomR (-100,100)) trials (undefined::Int16))
-    checkBounds "Int32 R"   (False,-100,100)  (approxBounds (randomR (-100,100)) trials (undefined::Int32))
-    checkBounds "Int64 R"   (False,-100,100)  (approxBounds (randomR (-100,100)) trials (undefined::Int64))
-    checkBounds "Word R"    (False,0,200)     (approxBounds (randomR (0,200))    trials (undefined::Word))
-    checkBounds "Word8 R"   (False,0,200)     (approxBounds (randomR (0,200))    trials (undefined::Word8))
-    checkBounds "Word16 R"  (False,0,200)     (approxBounds (randomR (0,200))    trials (undefined::Word16))
-    checkBounds "Word32 R"  (False,0,200)     (approxBounds (randomR (0,200))    trials (undefined::Word32))
-    checkBounds "Word64 R"  (False,0,200)     (approxBounds (randomR (0,200))    trials (undefined::Word64))
-    checkBounds "Double R" (True,10.0,77.0)   (approxBounds (randomR (10,77)) trials (undefined::Double))
-    checkBounds "Float R"  (True,10.0,77.0)   (approxBounds (randomR (10,77)) trials (undefined::Float))
-
-    checkBounds "CChar R"   (False,0,100)        (approxBounds (randomR (0,100))    trials (undefined:: CChar))
-    checkBounds "CSChar R"  (False,-100,100)     (approxBounds (randomR (-100,100)) trials (undefined:: CSChar))
-    checkBounds "CUChar R"  (False,0,200)        (approxBounds (randomR (0,200))    trials (undefined:: CUChar))
-    checkBounds "CShort R"  (False,-100,100)     (approxBounds (randomR (-100,100)) trials (undefined:: CShort))
-    checkBounds "CUShort R" (False,0,200)        (approxBounds (randomR (0,200))    trials (undefined:: CUShort))
-    checkBounds "CInt R"    (False,-100,100)     (approxBounds (randomR (-100,100)) trials (undefined:: CInt))
-    checkBounds "CUInt R"   (False,0,200)        (approxBounds (randomR (0,200))    trials (undefined:: CUInt))
-    checkBounds "CLong R"   (False,-100,100)     (approxBounds (randomR (-100,100)) trials (undefined:: CLong))
-    checkBounds "CULong R"     (False,0,200)     (approxBounds (randomR (0,200))    trials (undefined:: CULong))
-    checkBounds "CPtrdiff R"   (False,-100,100)  (approxBounds (randomR (-100,100)) trials (undefined:: CPtrdiff))
-    checkBounds "CSize R"      (False,0,200)     (approxBounds (randomR (0,200))    trials (undefined:: CSize))
-    checkBounds "CWchar R"     (False,0,100)     (approxBounds (randomR (0,100))    trials (undefined:: CWchar))
-    checkBounds "CSigAtomic R" (False,0,100)     (approxBounds (randomR (0,100))    trials (undefined:: CSigAtomic))
-    checkBounds "CLLong R"     (False,-100,100)  (approxBounds (randomR (-100,100)) trials (undefined:: CLLong))
-    checkBounds "CULLong R"    (False,0,200)     (approxBounds (randomR (0,200))    trials (undefined:: CULLong))
-    checkBounds "CIntPtr R"    (False,-100,100)  (approxBounds (randomR (-100,100)) trials (undefined:: CIntPtr))
-    checkBounds "CUIntPtr R"   (False,0,200)     (approxBounds (randomR (0,200))    trials (undefined:: CUIntPtr))
-    checkBounds "CIntMax R"    (False,-100,100)  (approxBounds (randomR (-100,100)) trials (undefined:: CIntMax))
-    checkBounds "CUIntMax R"   (False,0,200)     (approxBounds (randomR (0,200))    trials (undefined:: CUIntMax))
-
--- Untested:
--- instance Random Char where
--- instance Random Bool where
--- instance Random Integer where
diff --git a/tests/rangeTest.stdout b/tests/rangeTest.stdout
deleted file mode 100644 (file)
index 55ccaff..0000000
+++ /dev/null
@@ -1,67 +0,0 @@
-Int:  Passed
-Integer:  Passed
-Int8:  Passed
-Int16:  Passed
-Int32:  Passed
-Int64:  Passed
-Word:  Passed
-Word8:  Passed
-Word16:  Passed
-Word32:  Passed
-Word64:  Passed
-Double:  Passed
-Float:  Passed
-CChar:  Passed
-CSChar:  Passed
-CUChar:  Passed
-CShort:  Passed
-CUShort:  Passed
-CInt:  Passed
-CUInt:  Passed
-CLong:  Passed
-CULong:  Passed
-CPtrdiff:  Passed
-CSize:  Passed
-CWchar:  Passed
-CSigAtomic:  Passed
-CLLong:  Passed
-CULLong:  Passed
-CIntPtr:  Passed
-CUIntPtr:  Passed
-CIntMax:  Passed
-CUIntMax:  Passed
-Int R:  Passed
-Integer R:  Passed
-Int8 R:  Passed
-Int8 Rsmall:  Passed
-Int8 Rmini:  Passed
-Int8 Rtrivial:  Passed
-Int16 R:  Passed
-Int32 R:  Passed
-Int64 R:  Passed
-Word R:  Passed
-Word8 R:  Passed
-Word16 R:  Passed
-Word32 R:  Passed
-Word64 R:  Passed
-Double R:  Passed
-Float R:  Passed
-CChar R:  Passed
-CSChar R:  Passed
-CUChar R:  Passed
-CShort R:  Passed
-CUShort R:  Passed
-CInt R:  Passed
-CUInt R:  Passed
-CLong R:  Passed
-CULong R:  Passed
-CPtrdiff R:  Passed
-CSize R:  Passed
-CWchar R:  Passed
-CSigAtomic R:  Passed
-CLLong R:  Passed
-CULLong R:  Passed
-CIntPtr R:  Passed
-CUIntPtr R:  Passed
-CIntMax R:  Passed
-CUIntMax R:  Passed
diff --git a/tests/slowness.hs b/tests/slowness.hs
deleted file mode 100644 (file)
index 162a4cf..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-
--- http://hackage.haskell.org/trac/ghc/ticket/427
-
--- Two (performance) problems in one:
-
-{-# OPTIONS -fffi #-}
-module Main (main) where
-
-import Control.Monad
-import System.Random
-
-foreign import ccall unsafe "random" _crandom :: IO Int
-foreign import ccall unsafe "stdlib.hs" rand :: IO Int
-
-randomInt :: (Int, Int) -> IO Int
-randomInt (min,max) = do
---    n <- _crandom
-    n <- rand
-    return $ min + n `rem` range
-    where
-        range = max - min + 1
-
-main = replicateM_ (5*10^6) $ do
-    x <- randomRIO (0::Int,1000) :: IO Int
---    x <- randomInt (0::Int,1000) :: IO Int
-    x `seq` return ()
-    return ()
-
--- First, without the "seq" at the end, hardly anything is
--- evaluated and we're building huge amounts of thunks.
--- Three ideas about this one:
--- - Blame the user :)
--- - data StdGen = StdGen !Int !Int
---   Use strict fields in StdGen. Doesn't actually help
--- (at least in this example).
--- - Force evaluation of the StdGen in getStdRandom.
---   Does help in this example, but also changes behaviour
--- of the library:
---   x <- randomRIO undefined
---   currently dies only when x (or the result of a later
--- randomRIO) is evaluated. This change causes it to die
--- immediately.
-
--- Second, even _with_ the "seq", replacing "randomRIO" by
--- "randomInt" speeds the thing up with a factor of about
--- 30. (2 to 3.6, in a "real world" university practicum
--- exercise of 900 lines of code)
--- Even given the fact that they're not really doing the
--- same thing, this seems rather much :(
-
---------------------------------------------------------------------------------
-
--- [2011.06.28] RRN:
--- I'm currently seeing 1425 ms vs 43 ms for the above.  33X
--- difference. If I use rand() instead it's about 52ms.