В следующем примере:Использования runRVar в течение некоторого стека монады трансформатора
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
Я запутался:
почему подпись обув вынуждена быть
StateT Int RVar()
даже еслиtoss'
имеет подписьm Bool
для некоторыхMonadRandom m
Почему
testFoo
должен быть запущен с некоторымиStdRandom
, хотяtoss'
ужеrunRVar
сStdRandom
. Это имеет смысл с точки зрения типа, но в котором используетсяStdRandom
? Если этот вопрос имеет смысл вообще.Можно ли переписать подпись
foo
«s, какMonadRandom m => StateT Int m()
Тип 'runRVar' очень общий - в этом случае первый' runRVar' создается при типе 'RVar Bool -> StdRandom -> RVar Bool', когда вы используете' toss ' 'внутри' foo' и 'bar'. И эта функция - это только тождество (или должно быть). В любом случае StdRandom ничего не делает - когда вы пишете 'runRVar ... StdRandom', это просто означает использование интерфейса MonadRandom в качестве источника случайности. – user2407038