{-| Module : FiniteCategories
Description : Sample randomly a list.
Copyright : Guillaume Sabbagh 2021
License : GPL-3
Maintainer : guillaumesabbagh@protonmail.com
Stability : experimental
Portability : portable
Sample randomly a list.
-}
module Utils.Sample
(
pickOne,
sample
)
where
import System.Random (RandomGen, uniformR)
-- | Pick one element of a list randomly.
pickOne :: (RandomGen g) => [a] -> g -> (a,g)
pickOne [] g = error "pickOne in an empty list."
pickOne l g = ((l !! index),newGen) where
(index,newGen) = (uniformR (0,(length l)-1) g)
listWithoutNthElem :: [a] -> Int -> [a]
listWithoutNthElem [] _ = []
listWithoutNthElem (x:xs) 0 = xs
listWithoutNthElem (x:xs) k = x:(listWithoutNthElem xs (k-1))
-- | Sample /n/ elements of a list randomly.
sample :: (RandomGen g) => [a] -> Int -> g -> ([a],g)
sample _ 0 g = ([],g)
sample [] k g = error "Sample size bigger than the list size."
sample l n g = ((l !! index):rest,finalGen) where
(index,newGen) = (uniformR (0,(length l)-1) g)
new_l = listWithoutNthElem l index
(rest,finalGen) = sample new_l (n-1) newGen