我正在尝试学习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)
对于相同的参数,它们都给出相同的输出。但是在第一个版本中,要检查列表的长度(顺便说一下,这是状态),我引用的是 list s
。不过s
是在我做之前得到的put (a:s)
。所以当我检查长度时,我假设它会在我做之前给出's'的长度put (a:s)
。但似乎并非如此,因为如果两个版本的参数相同,则第一个版本的输出与第二个版本相同。
第二个版本至少对我来说更容易理解。在检查列表的长度之前ns
,我首先要做ns <- get
的是获取新的更新状态。
有人可以告诉我发生了什么吗?我觉得我严重误解了 Haskell 的工作方式或 State monad 本身的一些东西。
谢谢并恭祝安康。