单子变换器:IO和状态

4
这个问题与其他地方所涵盖的内容相似,但我尚未找到特别针对它的解决方法(至少没有一种我能够理解的方式)。
我想以依赖于各种随机选择方式的方式更新状态。由于我正在使用 RandomSource 类型类的实例,所有这些随机选择都存在于 IO monad 中,如下所示:
main :: IO Int
main = do
         a <- pickRand [1..7]
         return a

         where pickRand lst = runRVar (choice lst) DevRandom

我想要做的是类似以下的事情:存储类型为[Int]的状态,如果随机选择的列表元素a大于3,则将其推入状态。有什么建议吗?

请阅读有关 StateT 单子变换器的内容。 - Ankur
我已经尽力找到了好的资源,至少在我能力范围内。我所阅读的内容告诉我如何处理与我想要的有关的事情,例如如何通过lift $ print从状态单子打印。但是我还没有解决我的具体问题。 - user1604015
1个回答

4
import Control.Monad
import Control.Monad.Trans.State
import Control.Monad.IO.Class
import Data.Random.RVar
import Data.Random.Source.DevRandom
import Data.Random.List

myFun :: StateT [Int] IO ()
myFun = do
  lst <- get
  r <- liftIO $ runRVar (randomElement lst) DevRandom
  put $ if r > 3 then (r:lst) else lst
  return ()


main :: IO ()
main = evalStateT myFun [1..10] >>= print

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接