packages feed

FiniteCategories-0.1.0.0: src/Utils/Sample.hs

{-| 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