2013-02-24 127 views
2

我是新的Haskell,仍然试图理解一些基础知识。在编写递归函数时,我自然会以递归或尾递归的方式编写它们,而不必有意识地选择一个。将递归函数转换为尾递归

我的问题是:

  1. 鉴于任何递归函数,有没有一种简单的方法将其转换为尾递归?

  2. 给定一个尾递归函数,有没有简单的方法将其转换为递归?

示例功能

addOne [] = [] 
addOne (x:xs) = (x+1):addOne xs 

此外,写一个函数的时候,什么是一个简单的方法来判断是否尾递归是在替代比较合适?

+9

“给定一个尾递归函数,是否有简单的方法将其转换为递归?” - 每个尾递归函数都是自然递归的,不是吗? – 2013-02-24 20:44:03

+0

是的,但这与我的问题无关。编写一个递归和尾递归函数是两个完全不同的程序(语法上),可以完成相同的任务。所以可以转换为其他。 – AnchovyLegend 2013-02-24 20:50:57

+0

@Mi:不,尾递归函数总是递归的,函数不是与它自身“完全不同”,既不是语法也不是任何其他方面。 – 2013-02-25 00:43:30

回答

2

我是Haskell的新手。从我读过的内容可以看出,Haskell社区对显式递归是不满意的。相反,Haskell鼓励程序员使用标准函数,如map,filter,foldl,foldr等,它们封装了常见的递归操作。例如,

addOne [] = [] 
addOne (x:xs) = (x+1):addOne xs 

可以写成

addOne xs = map (+1) xs 

,或者要进一步使用无点式的步骤,如

addOne = map (+1) 

有可能的情况下,这些标准功能别不容易适应,你必须编写自己的递归函数。但是,我相信他们覆盖了90%的情况下你可能会试图实现显式递归。

我知道这并不完全回答你的问题,但我希望它给你一些想法来考虑。

1

鉴于任何递归函数,是否有一种简单的方法将其转换为 尾递归?

给出一个尾递归函数,有一个简单的方法来将其转换为递归?

是的。什么也不做,没有任何东西可以完成(老谢),就像@Joachim Breitner已经告诉你的那样。但是您对recursive的定义似乎偏离了常见的定义,因此您可能会告诉我们您的意思。

+0

+1,对于居高临下的无用答案。 – AnchovyLegend 2013-02-25 01:26:58