```{-# LANGUAGE NoIncoherentInstances #-}
{-# LANGUAGE NoMonomorphismRestriction #-}

module Vivid.Randomness (
pick
, picks
, exprand
, module System.Random.Shuffle
) where

import System.Random (Random)
import System.Random.Shuffle

-- | Picks a random element from the provided list
pick :: MonadRandom m => [a] -> m a
pick :: [a] -> m a
pick [a]
l = ([a]
l [a] -> Int -> a
forall a. [a] -> Int -> a
!!) (Int -> a) -> m Int -> m a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<\$> (Int, Int) -> m Int
forall (m :: * -> *) a. (MonadRandom m, Random a) => (a, a) -> m a
getRandomR (Int
0, (forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length::[a]->Int) [a]
l Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)

-- | Returns an infinite list of randomly-chosen elements from the provided list
--
--   e.g.
--
--   >> > take 5 <\$> picks [1,2,3,4]
--   >> [2,3,1,1,3]
picks :: (MonadRandom m) => [a] -> m [a]
picks :: [a] -> m [a]
picks [a]
l =
((Int -> a) -> [Int] -> [a]
forall a b. (a -> b) -> [a] -> [b]
map ([a]
l [a] -> Int -> a
forall a. [a] -> Int -> a
!!)) ([Int] -> [a]) -> m [Int] -> m [a]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<\$> (Int, Int) -> m [Int]
forall (m :: * -> *) a.
(a, a) -> m [a]
getRandomRs (Int
0, (forall a. [a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length::[a]->Int) [a]
l Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)

exprand :: (Fractional n, Floating n, MonadRandom m, Random n) => n -> n -> m n
exprand :: n -> n -> m n
exprand n
lo n
hi = do
n
r <- (n, n) -> m n
forall (m :: * -> *) a. (MonadRandom m, Random a) => (a, a) -> m a
getRandomR (n
0, n
1)
n -> m n
forall (f :: * -> *) a. Applicative f => a -> f a
pure (n -> m n) -> n -> m n
forall a b. (a -> b) -> a -> b
\$ n
lo n -> n -> n
forall a. Num a => a -> a -> a
* n -> n
forall a. Floating a => a -> a
exp (n -> n
forall a. Floating a => a -> a
log (n
hi n -> n -> n
forall a. Fractional a => a -> a -> a
/ n
lo) n -> n -> n
forall a. Num a => a -> a -> a
* n
r)
```