# New monads/MonadRandomSplittable

### From HaskellWiki

< New monads(Difference between revisions)

BrettGiles (Talk | contribs) m (heading/ link) |
BrettGiles (Talk | contribs) (Add links) |
||

Line 11: | Line 11: | ||

</haskell> |
</haskell> |
||

− | MonadRandomSplittable can then be derived for Rand by GHC: |
+ | MonadRandomSplittable can then be derived for Rand by [[GHC]]: |

<haskell> |
<haskell> |
||

newtype Rand g a = Rand { unRand :: RandomT g Identity a } |
newtype Rand g a = Rand { unRand :: RandomT g Identity a } |
||

Line 45: | Line 45: | ||

== Laws == |
== Laws == |
||

− | It is not clear to me exactly what laws <hask>splitRandom</hask> should satisfy. |
+ | It is not clear to me exactly what [[Monad laws|laws]] <hask>splitRandom</hask> should satisfy. |

For all terminating <hask>ma</hask> and <hask>mb</hask>, it should hold that |
For all terminating <hask>ma</hask> and <hask>mb</hask>, it should hold that |
||

Line 52: | Line 52: | ||

</haskell> |
</haskell> |
||

− | For monad transformers, it would also be nice if |
+ | For [[monad transformer]]s, it would also be nice if |

<haskell> |
<haskell> |
||

splitRandom undefined === splitRandom (return ()) >> lift undefined |
splitRandom undefined === splitRandom (return ()) >> lift undefined |

## Revision as of 19:53, 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)