2 回答

TA贡献2041条经验 获得超4个赞
那个of电话arrFold似乎有点不合适。
我不确定您arrFold是右折叠还是左折叠,但假设它是右折叠,您将需要像在递归实现中一样使用带有闭包的延续传递样式:
varArgs(ms => of(arrFold(g => mx => chain(mx) (g)) (f) (ms)))
变成
varArgs(ms => arrFold(go => mx => g => chain(mx) (x => go(g(x)))) (of) (ms) (f))
用左折叠,你可以写
varArgs(arrFold(mg => mx => chain(g => map(g) (mx)) (mg)) (of(f)))
但您需要注意,这构建了与正确折叠不同的调用树:
of(f)
chain(of(f))(g0 => map(m0)(g0))
chain(chain(of(f))(g0 => map(m0)(g0)))(g1 => map(m1)(g1))
chain(chain(chain(of(f))(g0 => map(m0)(g0)))(g1 => map(m1)(g1)))(g2 => map(m2)(g2))
vs(已经应用了延续)
of(f)
chain(m0)(x0 => of(f(x0)))
chain(m0)(x0 => chain(m1)(x1 => of(f(x0)(x1))))
chain(m0)(x0 => chain(m1)(x1 => chain(m2)(x2) => of(f(x0)(x1)(x2)))))
根据 monad 定律,它们的评估结果应该相同,但在实践中,一个可能比另一个更有效率。
添加回答
举报