如何从非递归版本定义斐波那契函数? 我正在学习C++。作为我自己的练习,我尝试使用Y组合器从非递归版本定义斐波那契函数
在F#()中,我会这样做:如何从非递归版本定义斐波那契函数? 我正在学习C++。作为我自己的练习,我尝试使用Y组合器从非递归版本定义斐波那契函数,c++,y-combinator,c++17,C++,Y Combinator,C++17,在F#()中,我会这样做: let rec Y f n = f (Y f) n let protoFib f x = if n > 1 then f(n-1) + f(n-2) else n let fib = Y protoFib C++中我如何定义y 这样下面的行就可以工作了 int protoFib(int f(int), int n) { return (n > 1) ? f(n-1) + f(n-2) : n; } int fib(int n) { retu
let rec Y f n = f (Y f) n
let protoFib f x = if n > 1 then f(n-1) + f(n-2) else n
let fib = Y protoFib
C++中我如何定义y
这样下面的行就可以工作了
int protoFib(int f(int), int n) {
return (n > 1) ? f(n-1) + f(n-2) : n;
}
int fib(int n) { return Y(protoFib, n); }
我尝试了以下函数声明(特定于int函数,因为我还没有研究过模板):
#包括
inty(std::function,int);
但是我一直在写函数定义
有什么建议吗?来自rosseta stone对Y combinator的建议:
template <typename F>
struct RecursiveFunc {
std::function<F(RecursiveFunc)> o;
};
template <typename A, typename B>
std::function<B(A)> Y (std::function<std::function<B(A)>(std::function<B(A)>)> f) {
RecursiveFunc<std::function<B(A)>> r = {
std::function<std::function<B(A)>(RecursiveFunc<std::function<B(A)>>)>([f](RecursiveFunc<std::function<B(A)>> w) {
return f(std::function<B(A)>([w](A x) {
return w.o(w)(x);
}));
})
};
return r.o(r);
}
模板
结构递归函数{
std::函数o;
};
模板
std::函数Y(std::函数f){
递归函数r={
函数([f](递归函数w){
返回f(std::function([w](ax){
返回w.o(w)(x);
}));
})
};
返回r.o(r);
}
我建议您检查该示例的整个代码,因为它包含实现它的其他方法(例如使用lambdas)首先,我将编写一个糟糕的Y-combinator(如果功能强大的话)
using fib_f = std::function<int(int)>;
using protofib_f = std::function< int( fib_f, int ) >;
int protofib( std::function<int(int)> f, int n) {
if (n>1) return f(n-1)+f(n-1);
return n;
}
auto Y( protofib_f f )->fib_f {
return [=](int n) { return f( Y(f), n ); };
}
template<class R>
auto Y = [&](auto&& f){
return [=](auto&&...args)->R {
return f( Y<R>(f), decltype(args)(args)... );
};
};
通过把它变成一只羔羊
改进的Y组合器需要更多的样板文件,因为lambdas无法访问:
template<class F>
struct y_combinate_t {
F f;
template<class...Args>
decltype(auto) operator()(Args&&...args)const {
return f(*this, std::forward<Args>(args)...);
}
};
template<class F>
y_combinate_t<std::decay_t<F>> y_combinate( F&& f ) {
return {std::forward<F>(f)};
};
有扣减指南
y_combinate{ protofib }
然后是一个完整的斐波那契函数
更进一步,您可以添加y combinator。谢谢您的回复。在丑陋的版本中,我不理解所有的语法。
Y(protofib\u f)->fib\u f
是否等同于fib\u f Y(protofib\u f)
?什么是[=]
?@ColonelPanic它是一个lamba介绍人<代码>[]启动lambda<代码>[=]启动lambda,该lambda隐式地从本地范围复制lambda主体中引用的任何内容。为了模仿F#的隐式curry,myY
接受一个函数并返回一个接受int
的std::function
,而不是接受一个函数和一个int
并依赖于curry它的语言。
using fib_f = std::function<int(int)>;
using protofib_f = std::function< int( fib_f, int ) >;
int protofib( std::function<int(int)> f, int n) {
if (n>1) return f(n-1)+f(n-1);
return n;
}
auto Y( protofib_f f )->fib_f {
return [=](int n) { return f( Y(f), n ); };
}
template<class R>
auto Y = [&](auto&& f){
return [=](auto&&...args)->R {
return f( Y<R>(f), decltype(args)(args)... );
};
};
template<class F>
struct y_combinate {
F f;
template<class...Args>
decltype(auto) operator()(Args&&...args)const {
return f(*this, std::forward<Args>(args)...);
}
};
template<class F>
y_combinate(F&& f)->y_combinate<std::decay_t<F>>;
y_combinate{ protofib }