[project @ 2003-11-26 09:55:22 by simonmar]
[haskell-directory.git] / System / Random.hs
index 6662549..eb7f626 100644 (file)
@@ -5,7 +5,7 @@
 -- License     :  BSD-style (see the file libraries/base/LICENSE)
 -- 
 -- Maintainer  :  libraries@haskell.org
--- Stability   :  provisional
+-- Stability   :  stable
 -- Portability :  portable
 --
 -- Random numbers.
@@ -44,20 +44,31 @@ module System.Random
 
 import Prelude
 
+#ifdef __NHC__
+import CPUTime         ( getCPUTime )
+import Foreign.Ptr      ( Ptr, nullPtr )
+#else
 import System.CPUTime  ( getCPUTime )
+import System.Time     ( getClockTime, ClockTime(..) )
+#endif
 import Data.Char       ( isSpace, chr, ord )
 import System.IO.Unsafe ( unsafePerformIO )
 import Data.IORef
 import Numeric         ( readDec )
 
-#ifdef __GLASGOW_HASKELL__
-import GHC.IOBase      ( stToIO )
-import System.Time     ( getClockTime, ClockTime(..) )
+-- 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__
+data ClockTime = TOD Integer ()
+foreign import ccall "time.h time" readtime :: Ptr () -> IO Int
+getClockTime :: IO ClockTime
+getClockTime = do t <- readtime nullPtr;  return (TOD (toInteger t) ())
 #endif
 
 {- $intro
 
-The "Random" library deals with the common task of pseudo-random
+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 
@@ -106,8 +117,8 @@ class RandomGen g where
    -- default mathod
    genRange g = (minBound,maxBound)
 
-{- |The "Random" library provides one instance of 'RandomGen', the abstract data
-type 'StdGen'.
+{- |The "System.Random" library provides one instance of 'RandomGen', the
+abstract data type 'StdGen'.
 
 The result of repeatedly using next should be at least as statistically robust
 as the /Minimal Standard Random Number Generator/ described by
@@ -223,7 +234,7 @@ class Random a where
 
   -- |Default methods  
   randoms  :: RandomGen g => g -> [a]
-  randoms  g      = x : randoms g' where (x,g') = random g
+  randoms  g      = (\(x,g') -> x : randoms g') (random g)
 
   randomRs :: RandomGen g => (a,a) -> g -> [a]
   randomRs ival g = x : randomRs ival g' where (x,g') = randomR ival g
@@ -271,20 +282,11 @@ instance Random Float where
   random g        = randomIvalDouble (0::Double,1) realToFrac g
   randomR (a,b) g = randomIvalDouble (realToFrac a, realToFrac b) realToFrac g
 
-#ifdef __GLASGOW_HASKELL__
 mkStdRNG :: Integer -> IO StdGen
 mkStdRNG o = do
     ct          <- getCPUTime
     (TOD sec _) <- getClockTime
     return (createStdGen (sec * 12345 + ct + o))
-#endif
-
-#ifdef __HUGS__
-mkStdRNG :: Integer -> IO StdGen
-mkStdRNG o = do
-    ct          <- getCPUTime
-    return (createStdGen (ct + o))
-#endif
 
 randomIvalInteger :: (RandomGen g, Num a) => (Integer, Integer) -> g -> (a, g)
 randomIvalInteger (l,h) rng
@@ -386,7 +388,7 @@ newStdGen = do
 
 {- |'getStdRandom' 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: 
+returned by the function. For example, @rollDice@ gets a random integer between 1 and 6: 
 
 >  rollDice :: IO Int
 >  rollDice = getStdRandom (randomR (1,6))