[commit: packages/random] master: Use GHC.Exts.build in randoms, randomRs to achieve fusion (4695ffa)
git at git.haskell.org
git at git.haskell.org
Thu Mar 19 15:44:36 UTC 2015
Repository : ssh://git@git.haskell.org/random
On branch : master
Link : http://git.haskell.org/packages/random.git/commitdiff/4695ffa366f659940369f05e419a4f2249c3a776
>---------------------------------------------------------------
commit 4695ffa366f659940369f05e419a4f2249c3a776
Author: Johan Kiviniemi <devel at johan.kiviniemi.name>
Date: Sun Jan 26 14:59:55 2014 +0200
Use GHC.Exts.build in randoms, randomRs to achieve fusion
>---------------------------------------------------------------
4695ffa366f659940369f05e419a4f2249c3a776
System/Random.hs | 27 +++++++++++++++++++++++++--
1 file changed, 25 insertions(+), 2 deletions(-)
diff --git a/System/Random.hs b/System/Random.hs
index 9a970c4..844dea8 100644
--- a/System/Random.hs
+++ b/System/Random.hs
@@ -96,6 +96,15 @@ import System.IO.Unsafe ( unsafePerformIO )
import Data.IORef
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
+
-- 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.
@@ -279,13 +288,15 @@ class Random a where
-- | 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 = x : randomRs ival g' where (x,g') = randomR ival g
+ 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 = (\(x,g') -> x : randoms g') (random g)
+ randoms g = build (\cons _nil -> buildRandoms cons random g)
-- | A variant of 'randomR' that uses the global random number generator
-- (see "System.Random#globalrng").
@@ -297,6 +308,18 @@ class Random a where
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
More information about the ghc-commits
mailing list