我正在尝试编写一个函数,其行为类似于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
使用的结构是否错误?
是否有正确的方法处理折叠内的随机/效果(有效)材料?