多次重复monadic计算并打印出结果? (MonadRandom)

时间:2013-05-13 10:44:33

标签: haskell monads monad-transformers

现在我正在使用MonadRandom库。我有一个计算:

metroChain :: (RandomGen g) => Rand g Double

我想多次执行,然后按顺序打印出结果。 或者更确切地说,我想创建一些多计算列表。

要做一次,我会用

main = do
  result <- evalRandIO metroChain
  print result

main = evalRandIO metroChain >>= (\result -> print result)

然而,我在打印任意(n)量的metroChain结果方面遇到了很多麻烦。

每个结果应该使用最后一个结果末尾给出的RandomGen ...... MonadRandom应该如何工作,对吗?

我已经研究过replicateMfmap和一些变形金刚(虽然我承认我似乎无法理解它们足以掌握它们对我的问题的应用)。

任何人都可以帮助我实现我正在寻找的功能吗?我觉得我错过了很简单的东西。但我对Haskell很新。

2 个答案:

答案 0 :(得分:4)

我将进行一次飞跃并假设metroStep是MCMC Metropolis-Hastings迭代。

你遇到的问题是你希望MH步骤是Markovian,但只是共享RandomGen状态,这正是replicateM n metroStep所做的,是不够的。这只能使每个步骤都能够基于独立的随机变量。要进行比较,如果未分享RandomGen州,则不变性将保证每个metroStep都相同。

所以你真正需要的是具有RandomGen状态的东西,以便提供一个伪随机数链,用于生成独立变量样本一个固定状态,以便在每一步你可以有P(x_i | theta, x_(i-1))。我们构建一个变换器堆栈来实现这一点 - 我将使用mtl库和random-fu,因为我几天前刚刚使用这些库编写了一个MCMC。

metroStep :: (MonadRandom m, MonadState StateSpace m) => m StateSpace

其中StateSpace是状态空间中的一个点,包括观察到一个未观察到的变量 - 它是似然函数右侧的每个参数。现在,replicateM n metroStep :: (MonadRandom m, MonadState StateSpace m) => m [StateSpace]是马尔可夫序列StateSpace点的列表。

然后我们像这样“运行”这个monad堆栈的具体版本

do steps <- (`runRVar` StdRandom) . (`evalStateT` ss0) $ (replicateM n metroStep)
   mapM_ print steps

答案 1 :(得分:3)

replicateM是您在构建随机计算时所需要的。 (除非电话的猜测是正确的。)

foo :: Int -> IO ()
foo n = do
    results <- evalRandIO (replicateM n metroStep)
    mapM_ print results

然后您希望mapM_帮助实际打印结果。

这样做你想要的吗?你有什么想让我继续扩展吗?