disco-0.2: src/Polysemy/Random.hs
{-# LANGUAGE TemplateHaskell #-}
-- This module was copied from polysemy-zoo:
-- https://hackage.haskell.org/package/polysemy-zoo-0.8.2.0/docs/src/Polysemy.Random.html
module Polysemy.Random (
-- * Effect
Random (..),
-- * Actions
random,
randomR,
-- * Interpretations
runRandom,
runRandomIO,
) where
import Polysemy
import Polysemy.State
import qualified System.Random as R
------------------------------------------------------------------------------
-- | An effect capable of providing 'R.Random' values.
data Random m a where
Random :: R.Random x => Random m x
RandomR :: R.Random x => (x, x) -> Random m x
makeSem ''Random
------------------------------------------------------------------------------
-- | Run a 'Random' effect with an explicit 'R.RandomGen'.
runRandom ::
forall q r a.
R.RandomGen q =>
q ->
Sem (Random ': r) a ->
Sem r (q, a)
runRandom q =
runState q
. reinterpret
( \case
Random -> do
~(a, q') <- gets @q R.random
put q'
pure a
RandomR r -> do
~(a, q') <- gets @q $ R.randomR r
put q'
pure a
)
{-# INLINE runRandom #-}
------------------------------------------------------------------------------
-- | Run a 'Random' effect by using the 'IO' random generator.
runRandomIO :: Member (Embed IO) r => Sem (Random ': r) a -> Sem r a
runRandomIO m = do
q <- embed @IO R.newStdGen
snd <$> runRandom q m
{-# INLINE runRandomIO #-}