我正在尝试编写递归匿名函数,到目前为止对我有用的是使用Y组合器。
%{ Call lambda function with any number of arguments. %}
call_ = @feval;
%{ Internal subroutine for function IF_. %}
if__ = @(varargin) varargin{3 - varargin{1}}();
%{ If predicate PRED is true, evaluate thunk IF_CLAUSE. %}
% { Otherwise, evaluate thunk ELSE_CLAUSE. %}
if_ = @(pred, if_clause, else_clause) if__(pred, if_clause, else_clause);
%{ Determine if X is a cell array. %}
is_cell_ = @(x) isa(x, 'cell');
%{ Call function FUNC with elements in argument list ARG_LS as arguments. %}
apply_ = @(func, arg_ls) if_(is_cell_(arg_ls), ...
@() func(arg_ls{:}), ...
@() func(arg_ls(:)));
%{ Compute a fixed point for the function H. %}
Y_ = @(h) call_(@(x) x(x), @(g) h(@(varargin) apply_(g(g), varargin)));
因此,例如,要定义阶乘,我们可以使用Y组合子:
make_fact__ = @(f) @(n, accum) if_(n == 0, @() accum, @() f(n - 1, n * accum))
fact__ = Y_(make_fact__)
fact_ = @(n) fact__(n, 1)
fact_(5)
注意上面定义的阶乘是尾递归。无论如何都要优化尾调用,这样尾递归函数不会为大N吹掉堆栈?
在互联网上搜索给我相同的Python问题(Does Python optimize tail recursion?),但我不能真正使用Octave / Matlab,仅使用匿名函数。
我还发现了一些关于蹦床的文章,我再次发现很难仅使用匿名函数来实现try-catch,这在蹦床的实现中是必需的。
谢谢!