{-# LANGUAGE ScopedTypeVariables #-}
module Immutable.Shuffle where
import Control.Monad.Primitive
import Control.Monad.Random (MonadRandom (..))
import Control.Monad.ST (runST)
import Data.Vector
import qualified Mutable.Shuffle as MS
import Prelude hiding (length, take)
import System.Random (RandomGen (..))
shuffle :: forall a g. RandomGen g => Vector a -> g -> (Vector a, g)
shuffle v g
| length v <= 1 = (v, g)
| otherwise =
runST $
do
mutV <- thaw v
newGen <- MS.shuffle mutV g
immutV <- unsafeFreeze mutV
pure (immutV, newGen)
shuffleM :: forall m a . (MonadRandom m, PrimMonad m) => Vector a -> m (Vector a)
shuffleM v
| length v <= 1 = pure v
| otherwise =
do
mutV <- thaw v
MS.shuffleM mutV
unsafeFreeze mutV
shuffleK :: forall m a . (MonadRandom m, PrimMonad m) => Int -> Vector a -> m (Vector a)
shuffleK k v
| length v <= 1 = pure v
| otherwise =
do
mutV <- thaw v
MS.shuffleK k mutV
unsafeFreeze mutV
sampleWithoutReplacement :: forall m a . (MonadRandom m, PrimMonad m) => Int -> Vector a -> m (Vector a)
{-# INLINEABLE sampleWithoutReplacement #-}
sampleWithoutReplacement k v = take k <$> shuffleK k v
maximalCycle :: forall a g. RandomGen g => Vector a -> g -> (Vector a, g)
maximalCycle v g
| length v <= 1 = (v, g)
| otherwise =
runST $
do
mutV <- thaw v
newGen <- MS.maximalCycle mutV g
immutV <- unsafeFreeze mutV
pure (immutV, newGen)
maximalCycleM :: forall m a . (MonadRandom m, PrimMonad m) => Vector a -> m (Vector a)
maximalCycleM v
| length v <= 1 = pure v
| otherwise =
do
mutV <- thaw v
MS.maximalCycleM mutV
unsafeFreeze mutV
derangement :: forall a g. (Eq a, RandomGen g) => Vector a -> g -> (Vector a, g)
derangement v g
| length v <= 1 = (v, g)
| otherwise =
runST $
do
mutV <- thaw v
newGen <- MS.derangement mutV g
immutV <- unsafeFreeze mutV
pure (immutV, newGen)
derangementM :: forall m a . (Eq a, MonadRandom m, PrimMonad m) => Vector a -> m (Vector a)
derangementM v
| length v <= 1 = pure v
| otherwise =
do
mutV <- thaw v
MS.derangementM mutV
unsafeFreeze mutV