用效果Monad折叠时,如何避免Purescript中的“太多递归”?

时间:2019-07-26 05:11:29

标签: purescript

我正在尝试编写一个函数,其行为类似于Clojure的reductions(即产生每个中间状态的列表)。另外,我需要此函数来处理随机值,因此可以住在Effect Monad中。

为此我想出的代码基本上是:

computeStuff :: Int -> Effect (Array Number)
computeStuff n = foldl  (\acc val -> do
    listOfTotals <- acc
    randNum <- random
    let nextEntry = (unsafeLast listOfTotals) * randNum
    pure $ snoc listOfTotals nextEntry
  )
  (pure [1.0])
  (range 0 n)

对于某个大小N,它将累积每个步骤生成的随机数的总和。

有一个人为的例子,但希望它能说明这一点。我正在尝试(a)在折叠时使用随机性,以及(b)在进行过程中跟踪结果。

这对于小型N来说效果很好,但对其他任何东西都“过多递归”而失败。甚至n=1000都会导致在Javascript方面引发异常。具体来说,它调出生成的__do()函数。

var computeStuff = function (n) {
    return Data_Foldable.foldl(Data_Foldable.foldableArray)(function (acc) {
        return function (val) {
            return function __do() {
                var v = acc();
                var v1 = Effect_Random.random();
                var nextEntry = UnsafeArrayUtil.last(v) * v1;
                return Data_Array.snoc(v)(nextEntry);
            };
        };
    })(Control_Applicative.pure(Effect.applicativeEffect)([ 1.0 ]))(Data_Array.range(0)(n));

当我在内部函数中使用monad时,foldl使用的结构是否错误?

是否有正确的方法处理折叠内的随机/效果(有效)材料?

0 个答案:

没有答案