HaskellStateモナドを学ぼうとしています。そこで、Stateモナドを使用して乱数のリストを生成する関数を作成しました。
これが最初のバージョンです。
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)
これが2番目のバージョンです。
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
。しかし、s
私がする前に得られましたput (a:s)
。したがって、長さを確認するときは、実行する前に「s」の長さになると想定しましたput (a:s)
。ただし、両方に同じパラメーターが指定されている場合、最初のバージョンの出力は2番目のバージョンと同じであるため、そうではないようです。
2番目のバージョンは、少なくとも私にとっては理解しやすいものです。リストの長さを確認する前に、ns
まずns <- get
新しい更新された状態を取得します。
誰かが何が起こっているのか教えてもらえますか?Haskellの仕組みや州のモナド自体について何かをひどく誤解しているような気がします。
よろしくお願いします。