状态monad的初始状态以及它如何首先传递

时间:2014-08-09 11:05:17

标签: haskell state monads

我正在阅读有关State monad的内容,在编写下面的代码后,我无法理解初始状态(mkStdGen 42)是如何传递到rollDice函数的?

get如何处理该初始值?

我理解rollDice函数是如何工作的,但我无法想象初始状态如何被提升到monad中。

import Control.Monad.Trans.State
import System.Random

rollDice :: State StdGen Int
rollDice = do
    generator <- get
    let (x, s) = randomR (1,6) generator
    put s
    return x

main :: IO ()
main = putStrLn . show $ evalState rollDice (mkStdGen 42)

1 个答案:

答案 0 :(得分:4)

为了简单起见,请将State s a视为一个函数,它采用初始状态s并返回一个值和一个新状态(a , s),就像在wikibook中一样:

newtype State s a = S { runState :: s -> (s , a) }

现在让我们使用rollDicePure = runState rollDice。什么是rollDicePure类型?鉴于runState仅删除State新类型,它应该是

rollDicePure :: StdGen -> (Int, StdGen)

所以runState(或evalState / execState)只需将有状态计算转换为一个简单函数,其参数为初始状态。

如果您想知道get如何获得此状态,请将其视为

getPure :: s -> (s, s)
getPure st = (st, st)

实际定义比这更复杂,但语义仍然存在。