如何分解这个 Haskell 表达式以避免重复计算?
我有这个函数(产生斐波那契数列):
unfoldr (\(p1, p2) -> Just (p1+p2, (p1+p2, p1)) ) (0, 1)
在这里,我注意到一个重复的表达式,p1+p2
,我想对其进行分解,以便只计算一次。加法本身并不是一个昂贵的计算,但对于更通用的版本:
unfoldr (\(p1, p2) -> Just (f p1 p2, (f p1 p2, p1)) ) (0, 1)
where f = arbitrary, possibly time-consuming function
在上述情况下, f p1 p2 被计算两次(除非有一些我不知道的神奇编译器优化),这如果 f
需要大量计算,可能会造成性能瓶颈。我无法将 f p1 p2
分解为 where
,因为 p1
和 p2
不在范围内。分解此表达式以便仅计算一次 f
的最佳方法是什么?
I have this function (produces the fibonacci sequence):
unfoldr (\(p1, p2) -> Just (p1+p2, (p1+p2, p1)) ) (0, 1)
In here, I notice a repeated expression, p1+p2
, which I would like to factor so that it is only calculated once. Addition itself isn't an expensive calculation, but for a more general version:
unfoldr (\(p1, p2) -> Just (f p1 p2, (f p1 p2, p1)) ) (0, 1)
where f = arbitrary, possibly time-consuming function
In the above situation, f p1 p2
is calculated twice (unless there's some magic compiler optimisation I don't know about), which could create a performance bottleneck if f
required a lot of computation. I can't factor f p1 p2
into a where
because p1
and p2
are not in scope. What is the best way to factor this expression so that f
is only calculated once?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
在
Control.Arrow
中有(&&&)
可以用于类似这样的内容:甚至:
在您的示例中
p1+ p2
实际上是下一个p1
所以你可以像这样重写它in
Control.Arrow
there is(&&&)
which can be used in something like this:or even:
As well in your example
p1+p2
is actually nextp1
so you can rewrite it like