recursionEngine termCond termFn reduceFn mapFn wayAheadFn =
recursiveFn
where recursiveFn y
| termCond y = termFn y
| otherwise = reduceFn (mapFn y) (recursiveFn (wayAheadFn y))
Then one can define, for example, factorial as follows.
factorial =
recursionEngine
(==0) -- termCond. Stop when we reach 0
(\_ -> 1) -- termFn. At 0, return 1.
(*) -- reduceFn. After the recursive call multiply n * factorial (n-1).
id -- mapFn. This is what's saved for the reduce function.
(+ (-1)) -- wayAheadFn. The recursive call is made on n-1.