New monads/MonadRandomSplittable
From HaskellWiki
(Difference between revisions)
(Add MonadRandomSplittable) |
m (heading/ link) |
||
| Line 1: | Line 1: | ||
[[Category:Code]] | [[Category:Code]] | ||
| - | + | When using [[New monads/MonadRandom]], one may also want to use a <hask>MonadRandom</hask> equivalent of <hask>RandomGen</hask>'s <hask>split</hask> function: | |
| - | + | ||
| - | When using [[New | + | |
<haskell> | <haskell> | ||
Revision as of 19:41, 17 November 2006
MonadRandom
RandomGen
split
class (MonadRandom m) => MonadRandomSplittable m where splitRandom :: m a -> m a instance (Monad m, RandomGen g) => MonadRandomSplittable (RandomT g m) where splitRandom ma = (RandomT . liftState) split >>= lift . evalRandomT ma
MonadRandomSplittable can then be derived for Rand by GHC:
newtype Rand g a = Rand { unRand :: RandomT g Identity a } deriving (Functor, Monad, MonadRandom, MonadRandomSplittable)
1 Example of usage
test :: Rand StdGen [Bool] -> (Int, [Bool], Int) test ma = evalRand (liftM3 (,,) (getRandomR (0,99)) ma (getRandomR (0,99))) (mkStdGen 0)
Then
*MonadRandom> test (replicateM 0 getRandom) (45,[],55) *MonadRandom> test (replicateM 2 getRandom) (45,[True,True],0) *MonadRandom> test (splitRandom $ replicateM 0 getRandom) (45,[],16) *MonadRandom> test (splitRandom $ replicateM 2 getRandom) (45,[False,True],16) *MonadRandom> case test undefined of (a,_,c) -> (a,c) *** Exception: Prelude.undefined *MonadRandom> case test (splitRandom undefined) of (a,_,c) -> (a,c) (45,16)
2 Laws
It is not clear to me exactly what lawssplitRandom
ma
mb
liftM3 (\a _ c -> (a,c)) getRandom ma getRandom === liftM3 (\a _ c -> (a,c)) getRandom mb getRandom
For monad transformers, it would also be nice if
splitRandom undefined === splitRandom (return ()) >> lift undefined
For example,
>runIdentity $ runRandomT (splitRandom (return ()) >> lift undefined >> return ()) (mkStdGen 0) ((),40014 2147483398) >runIdentity $ runRandomT (splitRandom undefined >> return ()) (mkStdGen 0) ((),40014 2147483398)
But
>runRandomT (splitRandom (return ()) >> lift undefined >> return ()) (mkStdGen 0) *** Exception: Prelude.undefined >runRandomT (splitRandom undefined >> return ()) (mkStdGen 0) *** Exception: Prelude.undefined
Rand
>runRand (splitRandom undefined >> return ()) (mkStdGen 0) ((),40014 2147483398)
3 Why?
InreplicateM 100 (splitRandom expensiveAction)
