我正在尝试学习Haskell State monad。因此,我编写了一个使用State monad生成随机数列表的函数。
这是第一个版本:
rnds :: Int -> [Int]
rnds n = evalState (help (mkStdGen 007)) []
where help prng = do s <- get
let (a, nprng) = randomR (1,6) prng
put (a:s)
if length s == n then (return s)
else (help nprng)
这是第二个版本。
rnds1 :: Int -> [Int]
rnds1 n = evalState (help (mkStdGen 007)) []
where help prng = do s <- get
let (a, nprng) = randomR (1,6) prng
put (a:s)
ns <- get
if length ns == n then (return ns)
else (help nprng)
对于相同的参数,它们都会给出相同的输出。但是在第一个版本中,为了检查列表(也就是状态)的长度,我引用了列表
s
。但是,在执行put (a:s)
之前,我获取了s
。因此,当我检查长度时,我假设它会给出在执行put (a:s)
之前's'的长度。但是似乎并不是这样,因为如果两个版本都给出相同的参数,则第一个版本的输出与第二个版本的输出相同。对于我来说,第二个版本更容易理解。在检查列表
ns
的长度之前,我首先执行ns <- get
以获取新的更新状态。请问有人可以告诉我发生了什么事吗?我有一种强烈的感觉,我严重误解了Haskell工作方式或State monad本身的某些内容。
谢谢和问候。