[project @ 2002-02-12 15:17:13 by simonmar]
[ghc-hetmet.git] / ghc / lib / std / Random.lhs
diff --git a/ghc/lib/std/Random.lhs b/ghc/lib/std/Random.lhs
deleted file mode 100644 (file)
index 1f19b20..0000000
+++ /dev/null
@@ -1,307 +0,0 @@
-% ------------------------------------------------------------------------------
-% $Id: Random.lhs,v 1.25 2001/08/29 10:49:28 simonmar Exp $
-%
-% (c) The University of Glasgow, 1995-2000
-%
-
-\section[Random]{Module @Random@}
-
-The June 1988 (v31 #6) issue of the Communications of the ACM has an
-article by Pierre L'Ecuyer called, "Efficient and Portable Combined
-Random Number Generators".  Here is the Portable Combined Generator of
-L'Ecuyer for 32-bit computers.  It has a period of roughly 2.30584e18.
-
-Transliterator: Lennart Augustsson
-
-sof 1/99 - code brought (kicking and screaming) into the new Random
-world..
-
-\begin{code}
-module Random
-       (
-         RandomGen(next, split, genRange)
-       , StdGen
-       , mkStdGen
-       , Random ( random,   randomR,
-                  randoms,  randomRs,
-                  randomIO, randomRIO )
-       , getStdRandom
-       , getStdGen
-       , setStdGen
-       , newStdGen
-       ) where
-
-#ifndef __HUGS__
-import PrelGHC         ( RealWorld )
-import PrelShow                ( showSignedInt, showSpace )
-import PrelRead                ( readDec )
-import PrelIOBase      ( unsafePerformIO, stToIO )
-import PrelArr         ( STRef, newSTRef, readSTRef, writeSTRef )
-import Time            ( getClockTime, ClockTime(..) )
-#else
-import PrelPrim                ( IORef
-                       , newIORef
-                       , readIORef
-                       , writeIORef
-                       , unsafePerformIO
-                       )
-#endif
-
-import CPUTime         ( getCPUTime )
-import Char            ( isSpace, chr, ord )
-\end{code}
-
-\begin{code}
-class RandomGen g where
-   next     :: g -> (Int, g)
-   split    :: g -> (g, g)
-   genRange :: g -> (Int,Int)
-
-   -- default mathod
-   genRange g = (minBound,maxBound)
-
-
-data StdGen 
- = StdGen Int Int
-
-instance RandomGen StdGen where
-  next  = stdNext
-  split = stdSplit
-
-#ifdef __HUGS__
-instance Show StdGen where
-  showsPrec p (StdGen s1 s2) = 
-     showsPrec p s1 . 
-     showChar ' ' .
-     showsPrec p s2
-#else
-instance Show StdGen where
-  showsPrec p (StdGen s1 s2) = 
-     showSignedInt p s1 . 
-     showSpace          . 
-     showSignedInt p s2
-#endif
-
-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)
-\end{code}
-
-\begin{code}
-mkStdGen :: Int -> StdGen -- why not Integer ?
-mkStdGen s
- | s < 0     = mkStdGen (-s)
- | otherwise = StdGen (s1+1) (s2+1)
-      where
-       (q, s1) = s `divMod` 2147483562
-       s2      = q `mod` 2147483398
-
-createStdGen :: Integer -> StdGen
-createStdGen s
- | s < 0     = createStdGen (-s)
- | otherwise = StdGen (fromInteger (s1+1)) (fromInteger (s2+1))
-      where
-       (q, s1) = s `divMod` 2147483562
-       s2      = q `mod` 2147483398
-
-\end{code}
-
-The class definition - see library report for details.
-
-\begin{code}
-class Random a where
-  -- Minimal complete definition: random and randomR
-  random  :: RandomGen g => g -> (a, g)
-  randomR :: RandomGen g => (a,a) -> g -> (a,g)
-  
-  randoms  :: RandomGen g => g -> [a]
-  randoms  g      = x : randoms g' where (x,g') = random g
-
-  randomRs :: RandomGen g => (a,a) -> g -> [a]
-  randomRs ival g = x : randomRs ival g' where (x,g') = randomR ival g
-
-  randomIO  :: IO a
-  randomIO        = getStdRandom random
-
-  randomRIO :: (a,a) -> IO a
-  randomRIO range  = getStdRandom (randomR range)
-\end{code}
-
-\begin{code}
-instance Random Int where
-  randomR (a,b) g = randomIvalInteger (toInteger a, toInteger b) g
-  random g        = randomR (minBound,maxBound) g
-
-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 (toInteger (bool2Int a), toInteger (bool2Int b)) g) of
-        (x, g) -> (int2Bool x, g)
-       where
-         bool2Int False = 0
-         bool2Int True  = 1
-
-        int2Bool 0     = False
-        int2Bool _     = True
-
-  random g       = randomR (minBound,maxBound) g
-instance Random Integer where
-  randomR ival g = randomIvalInteger ival g
-  random g      = randomR (toInteger (minBound::Int), toInteger (maxBound::Int)) g
-
-instance Random Double where
-  randomR ival g = randomIvalDouble ival id g
-  random g       = randomR (0::Double,1) g
-  
--- hah, so you thought you were saving cycles by using Float?
-instance Random Float where
-  random g        = randomIvalDouble (0::Double,1) realToFrac g
-  randomR (a,b) g = randomIvalDouble (realToFrac a, realToFrac b) realToFrac g
-\end{code}
-
-
-\begin{code}
-#ifdef __HUGS__
-mkStdRNG :: Integer -> IO StdGen
-mkStdRNG o = do
-    ct          <- getCPUTime
-    return (createStdGen (ct + o))
-#else
-mkStdRNG :: Integer -> IO StdGen
-mkStdRNG o = do
-    ct          <- getCPUTime
-    (TOD sec _) <- getClockTime
-    return (createStdGen (sec * 12345 + ct + o))
-#endif
-
-randomIvalInteger :: (RandomGen g, Num a) => (Integer, Integer) -> g -> (a, g)
-randomIvalInteger (l,h) rng
- | l > h     = randomIvalInteger (h,l) rng
- | otherwise = case (f n 1 rng) of (v, rng') -> (fromInteger (l + v `mod` k), rng')
-     where
-       k = h - l + 1
-       b = 2147483561
-       n = iLogBase b k
-
-       f 0 acc g = (acc, g)
-       f n acc g = 
-          let
-          (x,g')   = next g
-         in
-         f (n-1) (fromIntegral x + acc * b) g'
-
-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::Int), toInteger (maxBound::Int)) rng) of
-         (x, rng') -> 
-           let
-            scaled_x = 
-               fromDouble ((l+h)/2) + 
-                fromDouble ((h-l) / realToFrac intRange) *
-               fromIntegral (x::Int)
-           in
-           (scaled_x, rng')
-
-intRange :: Integer
-intRange  = toInteger (maxBound::Int) - toInteger (minBound::Int)
-
-iLogBase :: Integer -> Integer -> Integer
-iLogBase b i = if i < b then 1 else 1 + iLogBase b (i `div` b)
-
-stdNext :: StdGen -> (Int, StdGen)
-stdNext (StdGen s1 s2) = (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)
-\end{code}
-
-
-\begin{code}
-#ifdef __HUGS__
-
-setStdGen :: StdGen -> IO ()
-setStdGen sgen = writeIORef theStdGen sgen
-
-getStdGen :: IO StdGen
-getStdGen  = readIORef theStdGen
-
-theStdGen :: IORef StdGen
-theStdGen  = unsafePerformIO (newIORef (createStdGen 0))
-
-#else
-
-global_rng :: STRef RealWorld StdGen
-global_rng = unsafePerformIO $ do
-   rng <- mkStdRNG 0
-   stToIO (newSTRef rng)
-
-setStdGen :: StdGen -> IO ()
-setStdGen sgen = stToIO (writeSTRef global_rng sgen)
-
-getStdGen :: IO StdGen
-getStdGen = stToIO (readSTRef global_rng)
-
-#endif
-
-
-newStdGen :: IO StdGen
-newStdGen = do
-  rng <- getStdGen
-  let (a,b) = split rng
-  setStdGen a
-  return b
-
-getStdRandom :: (StdGen -> (a,StdGen)) -> IO a
-getStdRandom f = do
-   rng         <- getStdGen
-   let (v, new_rng) = f rng
-   setStdGen new_rng
-   return v
-\end{code}