Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/wix/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何从非递归版本定义斐波那契函数? 我正在学习C++。作为我自己的练习,我尝试使用Y组合器从非递归版本定义斐波那契函数_C++_Y Combinator_C++17 - Fatal编程技术网

如何从非递归版本定义斐波那契函数? 我正在学习C++。作为我自己的练习,我尝试使用Y组合器从非递归版本定义斐波那契函数

如何从非递归版本定义斐波那契函数? 我正在学习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

在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) { 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,my
Y
接受一个函数并返回一个接受
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 }