rhine-0.9: src/FRP/Rhine/ClSF/Random.hs
{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE TypeFamilies #-}
{- | Create 'ClSF's with randomness without 'IO'.
Uses the @MonadRandom@ package.
This module copies the API from @dunai@'s
'Control.Monad.Trans.MSF.Random'.
-}
module FRP.Rhine.ClSF.Random (
module FRP.Rhine.ClSF.Random,
module X,
)
where
-- transformers
import Control.Monad.IO.Class
-- MonadRandom
import Control.Monad.Random
-- dunai
import Control.Monad.Trans.MSF.Except (performOnFirstSample)
import Control.Monad.Trans.MSF.Random as X hiding (evalRandS, getRandomRS, getRandomRS_, getRandomS, runRandS)
import qualified Control.Monad.Trans.MSF.Random as MSF
-- rhine
import FRP.Rhine.ClSF.Core
import FRP.Rhine.ClSF.Random.Util
-- * Generating random values from the 'RandT' transformer
-- | Generates random values, updating the generator on every step.
runRandS ::
(RandomGen g, Monad m) =>
ClSF (RandT g m) cl a b ->
-- | The initial random seed
g ->
ClSF m cl a (g, b)
runRandS clsf = MSF.runRandS (morphS commuteReaderRand clsf)
-- | Updates the generator every step but discards the generator.
evalRandS ::
(RandomGen g, Monad m) =>
ClSF (RandT g m) cl a b ->
g ->
ClSF m cl a b
evalRandS clsf g = runRandS clsf g >>> arr snd
{- | Updates the generator every step but discards the value,
only outputting the generator.
-}
execRandS ::
(RandomGen g, Monad m) =>
ClSF (RandT g m) cl a b ->
g ->
ClSF m cl a g
execRandS clsf g = runRandS clsf g >>> arr fst
-- | Evaluates the random computation by using the global random generator.
evalRandIOS ::
Monad m =>
ClSF (RandT StdGen m) cl a b ->
IO (ClSF m cl a b)
evalRandIOS clsf = evalRandS clsf <$> newStdGen
-- | Evaluates the random computation by using the global random generator on the first tick.
evalRandIOS' ::
MonadIO m =>
ClSF (RandT StdGen m) cl a b ->
ClSF m cl a b
evalRandIOS' = performOnFirstSample . liftIO . evalRandIOS
-- * Creating random behaviours
-- | Produce a random value at every tick.
getRandomS ::
(MonadRandom m, Random a) =>
Behaviour m time a
getRandomS = constMCl getRandom
{- | Produce a random value at every tick,
within a range given per tick.
-}
getRandomRS ::
(MonadRandom m, Random a) =>
BehaviourF m time (a, a) a
getRandomRS = arrMCl getRandomR
{- | Produce a random value at every tick,
within a range given once.
-}
getRandomRS_ ::
(MonadRandom m, Random a) =>
(a, a) ->
Behaviour m time a
getRandomRS_ range = constMCl $ getRandomR range