random-extras 0.4 → 0.10
raw patch · 2 files changed
+42/−48 lines, 2 filesdep +random-fudep −MonadRandomdep −randomPVP ok
version bump matches the API change (PVP)
Dependencies added: random-fu
Dependencies removed: MonadRandom, random
API changes (from Hackage documentation)
- Control.Monad.Random.Extras: choice :: (MonadRandom m) => [a] -> m a
+ Control.Monad.Random.Extras: choice :: [a] -> RVar a
- Control.Monad.Random.Extras: choiceArray :: (MonadRandom m, IArray arr a, Ix i, Random i) => arr i a -> m a
+ Control.Monad.Random.Extras: choiceArray :: (IArray arr a, Ix i, Distribution Uniform i) => arr i a -> RVar a
- Control.Monad.Random.Extras: choiceExtract :: (MonadRandom m) => [a] -> m (Maybe ([a], a))
+ Control.Monad.Random.Extras: choiceExtract :: [a] -> Maybe (RVar ([a], a))
- Control.Monad.Random.Extras: choiceExtractSeq :: (MonadRandom m) => Seq a -> m (Maybe (Seq a, a))
+ Control.Monad.Random.Extras: choiceExtractSeq :: Seq a -> Maybe (RVar (Seq a, a))
- Control.Monad.Random.Extras: choiceSeq :: (MonadRandom m) => Seq a -> m a
+ Control.Monad.Random.Extras: choiceSeq :: Seq a -> RVar a
- Control.Monad.Random.Extras: choices :: (MonadRandom m) => [a] -> m [a]
+ Control.Monad.Random.Extras: choices :: Int -> [a] -> RVar [a]
- Control.Monad.Random.Extras: choicesArray :: (MonadRandom m, IArray arr a, Ix i, Random i) => arr i a -> m [a]
+ Control.Monad.Random.Extras: choicesArray :: (IArray arr a, Ix i, Distribution Uniform i) => Int -> arr i a -> RVar [a]
- Control.Monad.Random.Extras: iterativeChoice :: (MonadRandom m) => [a] -> m a
+ Control.Monad.Random.Extras: iterativeChoice :: [a] -> RVar a
- Control.Monad.Random.Extras: safeChoice :: (MonadRandom m) => [a] -> Maybe (m a)
+ Control.Monad.Random.Extras: safeChoice :: [a] -> Maybe (RVar a)
- Control.Monad.Random.Extras: safeChoiceSeq :: (MonadRandom m) => Seq a -> Maybe (m a)
+ Control.Monad.Random.Extras: safeChoiceSeq :: Seq a -> Maybe (RVar a)
- Control.Monad.Random.Extras: safeChoices :: (MonadRandom m) => [a] -> Maybe (m [a])
+ Control.Monad.Random.Extras: safeChoices :: Int -> [a] -> Maybe (RVar [a])
- Control.Monad.Random.Extras: sample :: (MonadRandom m) => Int -> [a] -> m [a]
+ Control.Monad.Random.Extras: sample :: Int -> [a] -> RVar [a]
- Control.Monad.Random.Extras: sampleSeq :: (MonadRandom m) => Int -> Seq a -> m [a]
+ Control.Monad.Random.Extras: sampleSeq :: Int -> Seq a -> RVar [a]
- Control.Monad.Random.Extras: shuffle :: (MonadRandom m) => [a] -> m [a]
+ Control.Monad.Random.Extras: shuffle :: [a] -> RVar [a]
- Control.Monad.Random.Extras: shuffleSeq :: (MonadRandom m) => Seq a -> m [a]
+ Control.Monad.Random.Extras: shuffleSeq :: Seq a -> RVar [a]
Files
- Control/Monad/Random/Extras.hs +39/−44
- random-extras.cabal +3/−4
Control/Monad/Random/Extras.hs view
@@ -1,3 +1,5 @@+{-# LANGUAGE FlexibleContexts #-}+ {- | Module : Control.Monad.Random.Extras Copyright : 2010 Aristid Breitkreuz@@ -5,11 +7,9 @@ Stability : experimental Portability : portable -Additional monadic random functions, based on 'MonadRandom'.-+Additional monadic random functions, based on random-fu. -} - module Control.Monad.Random.Extras ( -- * Random functions@@ -35,11 +35,12 @@ ) where -import Control.Monad (liftM)-import Control.Monad.Random (MonadRandom, getRandomR, getRandomRs)-import System.Random (Random)-import Data.List (mapAccumL, foldl')-import Data.Maybe (fromJust)+import Control.Monad+import Data.Random.RVar+import Data.Random.Distribution+import Data.Random.Distribution.Uniform+import Data.List+import Data.Maybe import qualified Data.Sequence as Seq import Data.Sequence ((><), ViewL((:<))) import qualified Data.Array.IArray as Arr@@ -61,12 +62,6 @@ where (a, r) = Seq.splitAt i s (b :< c) = Seq.viewl r -getRandomR' :: (MonadRandom m, Random a) => a -> a -> m a-getRandomR' = curry getRandomR--getRandomRNums :: (MonadRandom m, Random a, Num a) => [a] -> m [a]-getRandomRNums = mapM (getRandomR' 0)- backsaw :: Int -> [Int] backsaw n = [n - 1, n - 2 .. 0] @@ -78,16 +73,16 @@ -- of both methods should be comparable. -- -- /Complexity:/ O(n * log n), where /n/ is the length of the input list.-shuffle :: (MonadRandom m) => [a] -> m [a]+shuffle :: [a] -> RVar [a] shuffle = shuffleSeq . Seq.fromList -- | Shuffle a sequence randomly. This is being used by 'shuffle', -- so it logically uses the same method. -- -- /Complexity:/ O(n * log n), where /n/ is the length of the input sequence.-shuffleSeq :: (MonadRandom m) => Seq.Seq a -> m [a]+shuffleSeq :: Seq.Seq a -> RVar [a] shuffleSeq s = do- samples <- getRandomRNums . backsaw $ Seq.length s+ samples <- mapM (uniform 0) . backsaw $ Seq.length s return (shuffleSeq' s samples) shuffleSeq' :: Seq.Seq a -> [Int] -> [a]@@ -99,16 +94,16 @@ -- -- /Complexity:/ O(n + m * log n), where /n/ is the length of the input list -- and /m/ is the sample size.-sample :: (MonadRandom m) => Int -> [a] -> m [a]+sample :: Int -> [a] -> RVar [a] sample m = sampleSeq m . Seq.fromList -- | Take a random sample from a sequence. -- -- /Complexity:/ O(m * log n), where /n/ is the length of the input sequence -- and /m/ is the sample size.-sampleSeq :: (MonadRandom m) => Int -> Seq.Seq a -> m [a]+sampleSeq :: Int -> Seq.Seq a -> RVar [a] sampleSeq m s = do- samples <- getRandomRNums . take m . backsaw $ Seq.length s+ samples <- mapM (uniform 0) . take m . backsaw $ Seq.length s return (shuffleSeq' s samples) -- Choice@@ -116,30 +111,30 @@ -- | Randomly choose and extract an element from a list. -- -- /Complexity:/ O(n), where /n/ is the length of the input list.-choiceExtract :: (MonadRandom m) => [a] -> m (Maybe ([a], a))-choiceExtract [] = return Nothing-choiceExtract xs = extract xs `liftM` getRandomR (0, length xs - 1)+choiceExtract :: [a] -> Maybe (RVar ([a], a))+choiceExtract [] = Nothing+choiceExtract xs = Just $ (fromJust . extract xs) `liftM` uniform 0 (length xs - 1) -- | Randomly choose and extract an element from a sequence. -- -- /Complexity:/ O(log n), where /n/ is the length of the input sequence.-choiceExtractSeq :: (MonadRandom m) => Seq.Seq a -> m (Maybe (Seq.Seq a, a))-choiceExtractSeq s | Seq.null s = return Nothing- | otherwise = extractSeq s `liftM` getRandomR (0, Seq.length s - 1)+choiceExtractSeq :: Seq.Seq a -> Maybe (RVar (Seq.Seq a, a))+choiceExtractSeq s | Seq.null s = Nothing+ | otherwise = Just $ (fromJust . extractSeq s) `liftM` uniform 0 (Seq.length s - 1) -- | Select a random element from a list. -- -- /Partial function:/ This function is only defined on non-empty lists. -- -- /Complexity:/ O(n), where /n/ is the length of the input list.-choice :: (MonadRandom m) => [a] -> m a+choice :: [a] -> RVar a choice [] = error "Control.Monad.Random.Extras.choice: empty list"-choice xs = (xs !!) `liftM` getRandomR (0, length xs - 1)+choice xs = (xs !!) `liftM` uniform 0 (length xs - 1) -- | Safely select a random element from a list. -- -- /Complexity:/ O(n), where /n/ is the length of the input list.-safeChoice :: (MonadRandom m) => [a] -> Maybe (m a)+safeChoice :: [a] -> Maybe (RVar a) safeChoice [] = Nothing safeChoice xs = Just $ choice xs @@ -149,11 +144,11 @@ -- with a length below ('maxBound' + 1 :: Int). -- -- /Complexity:/ O(n), where /n/ is the length of the input list.-iterativeChoice :: MonadRandom m => [a] -> m a+iterativeChoice :: [a] -> RVar a iterativeChoice xs = fst `liftM` foldl' stepM (return start) xs where stepM x y = x >>= step y step offered (old, n) = do- i <- getRandomR (0, n)+ i <- uniform 0 n let new | i == 0 = offered | otherwise = old return $! new `seq` (new, n + 1)@@ -165,22 +160,22 @@ -- /Partial function:/ This function is only defined on non-empty sequences. -- -- /Complexity:/ O(log n), where /n/ is the length of the input sequence.-choiceSeq :: (MonadRandom m) => Seq.Seq a -> m a+choiceSeq :: Seq.Seq a -> RVar a choiceSeq s | Seq.null s = error "Control.Monad.Random.Extras.choiceSeq: empty sequence"- | otherwise = Seq.index s `liftM` getRandomR (0, Seq.length s - 1)+ | otherwise = Seq.index s `liftM` uniform 0 (Seq.length s - 1) -- | Safely select a random element from a sequence. -- -- /Complexity:/ O(log n), where /n/ is the length of the input sequence.-safeChoiceSeq :: (MonadRandom m) => Seq.Seq a -> Maybe (m a)+safeChoiceSeq :: Seq.Seq a -> Maybe (RVar a) safeChoiceSeq s | Seq.null s = Nothing | otherwise = Just $ choiceSeq s -- | Select a random element from an array. -- -- /Complexity:/ O(1).-choiceArray :: (MonadRandom m, Arr.IArray arr a, Arr.Ix i, Random i) => arr i a -> m a-choiceArray v = (v !) `liftM` getRandomR (Arr.bounds v)+choiceArray :: (Arr.IArray arr a, Arr.Ix i, Distribution Uniform i) => arr i a -> RVar a+choiceArray v = (v !) `liftM` uncurry uniform (Arr.bounds v) -- Choices @@ -189,20 +184,20 @@ -- /Partial function:/ This function is only defined on non-empty lists. -- -- /Complexity:/ O(n) base and O(1) per element.-choices :: (MonadRandom m) => [a] -> m [a]-choices [] = error "Control.Monad.Random.Extras.choices: empty list"-choices xs = choicesArray $ Data.Array.listArray (1, length xs) xs+choices :: Int -> [a] -> RVar [a]+choices _ [] = error "Control.Monad.Random.Extras.choices: empty list"+choices n xs = choicesArray n $ Data.Array.listArray (1, length xs) xs -- | Safely get a stream of random elements from a list. -- -- /Complexity:/ O(n) base and O(1) per element, where /n/ is the length of -- the input list.-safeChoices :: (MonadRandom m) => [a] -> Maybe (m [a])-safeChoices [] = Nothing-safeChoices xs = Just $ choices xs+safeChoices :: Int -> [a] -> Maybe (RVar [a])+safeChoices _ [] = Nothing+safeChoices n xs = Just $ choices n xs -- | A stream of random elements from an array. -- -- /Complexity:/ O(1) per element.-choicesArray :: (MonadRandom m, Arr.IArray arr a, Arr.Ix i, Random i) => arr i a -> m [a]-choicesArray v = map (v !) `liftM` getRandomRs (Arr.bounds v)+choicesArray :: (Arr.IArray arr a, Arr.Ix i, Distribution Uniform i) => Int -> arr i a -> RVar [a]+choicesArray n v = map (v !) `liftM` replicateM n (uncurry uniform (Arr.bounds v))
random-extras.cabal view
@@ -7,13 +7,13 @@ -- The package version. See the Haskell package versioning policy -- (http://www.haskell.org/haskellwiki/Package_versioning_policy) for -- standards guiding when and how versions should be incremented.-Version: 0.4+Version: 0.10 -- A short (one-line) description of the package. Synopsis: Additional functions for random values. -- A longer description of the package.-Description: Additional functions for random values, based on MonadRandom. Inspired by random-shuffle.+Description: Additional functions for random values, based on random-fu. Inspired by random-shuffle. -- URL for the project homepage or repository. Homepage: http://github.com/aristidb/random-extras@@ -56,8 +56,7 @@ base >=4 && <5, containers ==0.3.*, array ==0.3.*,- random ==1.0.0.*,- MonadRandom ==0.1.*+ random-fu ==0.1.* -- Modules not exported by this package. -- Other-modules: