Tail recursion
From HaskellWiki
A recursive function is tail recursive if the final result of the recursive call is the final result of the function itself. If the result of the recursive call must be further processed (say, by adding 1 to it, or consing another element onto the beginning of it), it is not tail recursive.
Here is formal definition of "tail recursive". "f occurs in t" means f is a free variable of t.
When a function is defined (in let or at the top level) as:
f = t
where f is a name and t is a lambda-term, f is tail recursive iff f occurs tail recursively in t. f occurs tail recursively in t iff f occurs in t and any of the following holds:
-
tis variable; -
tis "\var -> t0" andfoccurs tail recursively int0; -
tis "t0 t1" andfoccurs tail recursively int0and does not occur int1; -
tis "let bs in t0" andfoccurs tail recursively int0and for each binder "var = t1" inbs,fdoes not occur int1; -
tis "case t0 of bs" andfdoes not occur int0and for each branchbinbs,fdoes not occur or occurs tail recursively inb;- when we are saying "occur in
b",bhas form "D vars -> t" (whereDis some data constructor andvarsis a sequence of names), we are thinking of the lambda-abstraction "\vars -> t" instead ofb.
- when we are saying "occur in
Note that foldl is tail recursive.
The important concept to know in Haskell is guarded recursion (see tail recursion modulo cons), where any recursive calls occur within a data constructor (such asfoldr
(:)
Source
- Brent Yorgey in Haskell-Cafe on Definition of "tail recursive" wrt Folds
