Как связать, положить и вернуть взаимодействовать здесь?
Учитывая следующий код
rollDie :: GeneratorState Int
rollDie = do generator <- get
let (value, newGenerator) = randomR (1,6) generator
put newGenerator
return value
Я знаю, что могу перевести это как:
rollDie2 :: GeneratorState Int
rollDie2 = get >>= \generator ->let (value, newGenerator) = randomR(1,6) generator
in put newGenerator >> return value
Я проверил обе функции с и без put newGenerator >>
и они дают разные результаты. У меня вопрос почему? put
функции чисто, а оператор (>>
) Значит это return value
не должны зависеть от предыдущих результатов.
1 ответ
Когда я тестирую обе функции с одинаковым начальным состоянием, я получаю один и тот же ответ:
λ> evalState rollDie (mkStdGen 0)
6
λ> evalState rollDie2 (mkStdGen 0)
6
Я подозреваю, что вы не используете одно и то же состояние для обоих тестов. Как именно вы тестируете функции?
Вот пример, где состояние (то есть генератор случайных чисел) изменяется:
test :: GeneratorState (Int, Int)
test = do
a <- rollDie -- modifies the state!
b <- rollDie2 -- gets a different state
return (a, b)
runTest :: IO ()
runTest = do
g <- getStdGen
let (a, b) = evalState test g
print a
print b
Как вы можете видеть, когда вы запускаете это, вы получаете два разных ответа.
λ> runTest
4
2