我正在尝试从列表中选择一个随机元素,但这会使函数不纯,因此无法编译。如何使递归函数接受IO操作?
build :: Jabberwocky Integer String Syllables -> String
build (Jabberwocky 0 body syl) = body
build (Jabberwocky len body syl)
| syl == Middle = build (Jabberwocky (len - 1) (body ++ (rand middle) ) Consonant)
| syl == Consonant = build (Jabberwocky (len - 1) (body ++ (rand consonant)) Vowel)
| syl == Vowel = build (Jabberwocky (len - 1) (body ++ (rand vowel) ) Consonant)
| syl == Ending = build (Jabberwocky (len - 1) (body ++ (rand ending) ) Vowel)
where
rand = getStdRandom (randomR (1,6))
最佳答案
您必须将生成器带入纯流程(链接新的随机生成器状态)
randomR_nTimes_rec :: (RandomGen g, Random a) => Int -> (a, a) -> g -> ([a], g)
randomR_nTimes_rec 0 _ g = ([], g)
randomR_nTimes_rec n i g = (x:xs, g'') where ( x, g' ) = randomR i g
(xs, g'') = randomR_nTimes_rec (n - 1) i g'
用法
*Main> getStdGen >>= return . randomR_nTimes_rec 5 (0,5)
([2,5,3,1,3],1206240749 652912057)
如果您应该将随机状态携带到复杂的过程中,可能会有用
Control.Monad.Random
with example