English 中文(简体)
是否有问题无法用尾 re来书写?
原标题:Are there problems that cannot be written using tail recursion?

旅行是一种重要的业绩选择,使用功能性语言,因为它允许休养的电话消费固定的 st(而不是O(n))。

是否有任何问题根本无法用尾语书写,或者是否总是有可能将神经性风险功能转化为尾声?

如果是的话,有一天可以让职能汇编者和口译人员充分了解情况,以便自动进行转换?

最佳回答

是的,实际是。 采用某种代码,将每项功能要求——每次返回——改为尾声。 你最后说的是所谓的连续绕行风格,或CPS。

例如,这里的职能包括两个休养电话:

(define (count-tree t)
  (if (pair? t)
    (+ (count-tree (car t)) (count-tree (cdr t)))
    1))

在这里,如果你将这一职能转换为继续绕行方式,将如何研究:

(define (count-tree-cps t ctn)
  (if (pair? t)
    (count-tree-cps (car t)
                    (lambda (L) (count-tree-cps (cdr t)
                                                (lambda (R) (ctn (+ L R))))))
    (ctn 1)))

附加论点,ctn,是count-tree-cps。 详见<>。 (vc) 回答说,你可以在O(1)空间做一切事,这是正确的;在此,每一次继续是关闭,引起一些记忆。)

我将电话转换为<条码>、<>条/代码>或<条码>cdr或<条码>+>/条码>。 这也是可以做到的,但我假设这些传单实际上将登上线。

现在请查阅:Chicken 计划。 Chicken never Return汇编的程序。 1994年在奇肯特执行之前撰写的一篇古典论文解释为什么会发生这种阴谋:上的切尼

简言之,继续绕行方式在 Java文中相当常见。 您可使用进行长期计算,避免浏览器的“低档”。 并且吸引了异同步的APICAES。 (XMLHttpRequest周围的简单包装)显然处于连续绕行的风格;最后的论点是一种功能。

问题回答

看到任何相互宽恕的职能都可能变成一种适时的职能,这是真实的,但并不有用。 这一观察与1960年代旧的花nut一样,即可以消除控制流的建筑,因为每个方案都可以作为在内部张贴的个案说明撰写。

了解的有益之处是,增加 累积参数<>后,许多并非明显杂质的功能可以转换成尾料。 (这种转变的一个极端版本是向继续绕行式转变,但大多数方案家认为,CPS变革的产出难以阅读)。)

这里的一个例子是“风险”职能(实际上它只是重复性的),但并非详尽的:

factorial n = if n == 0 then 1 else n * factorial (n-1)

In this case the multiply happens after the recursive call. We can create a version that is tail-recursive by putting the product in an accumulating parameter:

factorial n = f n 1
  where f n product = if n == 0 then product else f (n-1) (n * product)

内部职能<代码>f是详细保险,并汇编成一个严格的循环。


我认为以下区别是有益的:

  • In an iterative or recursive program, you solve a problem of size n by first solving one subproblem of size n-1. Computing the factorial function falls into this category, and it can be done either iteratively or recursively. (This idea generalizes, e.g., to the Fibonacci function, where you need both n-1 and n-2 to solve n.)

  • In a recursive program, you solve a problem of size n by first solving two subproblems of size n/2. Or, more generally, you solve a problem of size n by first solving a subproblem of size k and one of size n-k, where 1 < k < n. Quicksort and mergesort are two examples of this kind of problem, which can easily be programmed recursively, but is not so easy to program iteratively or using only tail recursion. (You essentially have to simulate recursion using an explicit stack.)

  • In dynamic programming, you solve a problem of size n by first solving all subproblems of all sizes k, where k<n. Finding the shortest route from one point to another on the London Underground is an example of this kind of problem. (The London Underground is a multiply-connected graph, and you solve the problem by first finding all points for which the shortest path is 1 stop, then for which the shortest path is 2 stops, etc etc.)

只有第一类方案有simple转换成复合再保险形式。

http://en.wikipedia.org/wiki/Tak_(功能)”rel=“nofollow noreferer”>tak 。 只能使用尾声。 (不允许继续)





相关问题
Recursive same-table query in SQL Server 2008

I have the following table in a SQL Server 2008 database: Id Name ParentFolder -- ---- ------------ 1 Europe NULL 2 Asia NULL 3 Germany 1 4 UK 1 5 China ...

Finding a class within list

I have a class (Node) which has a property of SubNodes which is a List of the Node class I have a list of Nodes (of which each Node may or may not have a list of SubNodes within itself) I need to be ...

Selecting records during recursive stored procedure

I ve got a content management system that contains a hierarchical structure of categories, with sub-categories subject to different ordering options at each level. Currently, that s retrieved by a (...

热门标签