module Utils.Sample
(
pickOne,
sample
)
where
import System.Random (RandomGen, uniformR)
pickOne :: (RandomGen g) => [a] -> g -> (a,g)
pickOne :: forall g a. RandomGen g => [a] -> g -> (a, g)
pickOne [] g
g = [Char] -> (a, g)
forall a. HasCallStack => [Char] -> a
error [Char]
"pickOne in an empty list."
pickOne [a]
l g
g = (([a]
l [a] -> Int -> a
forall a. [a] -> Int -> a
!! Int
index),g
newGen) where
(Int
index,g
newGen) = ((Int, Int) -> g -> (Int, g)
forall g a. (RandomGen g, UniformRange a) => (a, a) -> g -> (a, g)
uniformR (Int
0,([a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [a]
l)Int -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) g
g)
listWithoutNthElem :: [a] -> Int -> [a]
listWithoutNthElem :: forall a. [a] -> Int -> [a]
listWithoutNthElem [] Int
_ = []
listWithoutNthElem (a
x:[a]
xs) Int
0 = [a]
xs
listWithoutNthElem (a
x:[a]
xs) Int
k = a
xa -> [a] -> [a]
forall a. a -> [a] -> [a]
:([a] -> Int -> [a]
forall a. [a] -> Int -> [a]
listWithoutNthElem [a]
xs (Int
kInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1))
sample :: (RandomGen g) => [a] -> Int -> g -> ([a],g)
sample :: forall g a. RandomGen g => [a] -> Int -> g -> ([a], g)
sample [a]
_ Int
0 g
g = ([],g
g)
sample [] Int
k g
g = [Char] -> ([a], g)
forall a. HasCallStack => [Char] -> a
error [Char]
"Sample size bigger than the list size."
sample [a]
l Int
n g
g = (([a]
l [a] -> Int -> a
forall a. [a] -> Int -> a
!! Int
index)a -> [a] -> [a]
forall a. a -> [a] -> [a]
:[a]
rest,g
finalGen) where
(Int
index,g
newGen) = ((Int, Int) -> g -> (Int, g)
forall g a. (RandomGen g, UniformRange a) => (a, a) -> g -> (a, g)
uniformR (Int
0,([a] -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length [a]
l)Int -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) g
g)
new_l :: [a]
new_l = [a] -> Int -> [a]
forall a. [a] -> Int -> [a]
listWithoutNthElem [a]
l Int
index
([a]
rest,g
finalGen) = [a] -> Int -> g -> ([a], g)
forall g a. RandomGen g => [a] -> Int -> g -> ([a], g)
sample [a]
new_l (Int
nInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
1) g
newGen