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