Reputation: 4895
In the following example:
toss :: Double -> RVar Bool
toss p = do
q <- uniform 0 1
return $ q <= p
toss' :: MonadRandom m => Double -> m Bool
toss' p = runRVar (toss p) StdRandom
foo :: StateT Int RVar ()
foo = do
h <- lift $ toss' 0.5
if h then put 100 else put 0
bar :: StateT Int RVar ()
bar = do
h <- lift $ toss 0.5
if h then put 404 else put 200
testFoo :: MonadRandom m => m ((), Int)
testFoo = runRVar (runStateT foo 0) StdRandom
testBar :: MonadRandom m => m ((), Int)
testBar = runRVar (runStateT bar 0) StdRandom
I am confused about:
why the signature of foo is forced to be StateT Int RVar ()
even though toss'
has signature m Bool
for some MonadRandom m
Why testFoo
has to be run with some StdRandom
even though toss'
already runRVar
with StdRandom
. It makes sense from a type perspective, but which StdRandom
end up being used? If this question makes any sense at all.
Would it be possible to rewrite foo
's signature as MonadRandom m => StateT Int m ()
Upvotes: 0
Views: 113
Reputation: 118
RVar
to the monad stack like you did in bar
. MonadRandom
is too general.
StdRandom
is just a data constructor, so it has no specific state. random-fu
should handle updating state automatically.Upvotes: 4