【问题标题】:What is this functional programming optimization called?这种函数式编程优化叫什么?
【发布时间】:2020-03-18 19:46:57
【问题描述】:

考虑以下用于计算第 n 个斐波那契数的 Haskell 代码。

fib :: Int -> Int
fib 0 = 0
fib 1 = 1
fib n = fib (n - 1) + fib (n - 2)

这段代码很慢。我们可以通过重构为“迭代”计算的辅助函数来优化它,通过“存储”所有相关数据以计算其参数中的递归,以及一个告诉我们计算多长时间的“计数器”。

fastfib :: Int -> Int
fastfib n = helper 1 0 n
  where
    helper a _ 1 = a
    helper a b i = helper (a + b) a (i - 1)

似乎这种优化也可以应用得更广泛。它在函数式编程社区或其他地方有名字吗?

【问题讨论】:

  • 这不是简单的重构。它完全改变了算法。充其量,它是高级记忆的一种形式:使用记忆我们会记住所有先前计算的结果,而在这种情况下,我们只记得最后两个,因为那是我们需要的。您还可以在算法中看到类似技术的“动态编程”。
  • @chi 是的,我同意这不是简单的重构。
  • 你熟悉memoization吗?

标签: haskell optimization functional-programming recurrence


【解决方案1】:

是的,它被称为accumulating parameter 技术。 (这里是one of my answers,关于它)。

tail-recursion-modulo-cons(“TRMC”)、hylomorphisms、folding等密切相关。

Monoids 启用重新括号

a+(b+(c+...)) == (a+b)+(c+...) == ((a+b)+c)+...

这使得积累。 TRMC(在 Prolog 的上下文中被明确地知道)是相同的,只是列表;

[a]++([b]++([c]++...)) == ([a]++[b])++([c]++...) == (([a]++[b])++[c])++...

corecursion 以自上而下的方式构建列表,就像 TRMC 一样。

上面链接的答案包含一个指向 Friedman 和 Wise 的 technical report from 1974 的链接,作为示例,它基本上讨论了在 + 幺半群的上下文中的积累。

斐波那契示例中没有幺半群,但可以说是“知识”的积累,因为我们从一个斐波那契数到下一个。

【讨论】:

猜你喜欢
  • 2011-10-31
  • 2015-11-06
  • 2011-08-28
  • 1970-01-01
  • 2016-09-13
  • 2019-11-19
  • 2016-02-06
相关资源
最近更新 更多