-->

用C固定点组合++(Fixed point combinators in C++)

2019-08-17 07:52发布

我感兴趣的是使用固定点组合(如实际例子的Y组合子在C ++中,你是否曾经使用与不动点组合子蛋或绑定在活生生的代码?

我发现,在鸡蛋有点晦涩难懂这个例子:

void egg_example()
{
    using bll::_1;
    using bll::_2;

    int r =
        fix2(
            bll::ret<int>(
                // \(f,a) -> a == 0 ? 1 : a * f(a-1)
                bll::if_then_else_return( _2 == 0,
                    1,
                    _2 * lazy(_1)(_2 - 1)
                )
            )
        ) (5);

    BOOST_CHECK(r == 5*4*3*2*1);
}

你能解释这一切是如何工作的?

是否有可能使用绑定一个比这也许依赖关系较少的一个很好的简单的例子?

Answer 1:

这里是转换成相同代码boost::bind通知的Y组合子,并在主函数中的应用网站。 我希望这有帮助。

#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <iostream>

// Y-combinator compatible factorial
int fact(boost::function<int(int)> f,int v)
{
  if(v == 0)
    return 1;
  else
    return v * f(v -1);
}

// Y-combinator for the int type
boost::function<int(int)>
    y(boost::function<int(boost::function<int(int)>,int)> f)
{
  return boost::bind(f,boost::bind(&y,f),_1);
}


int main(int argc,char** argv)
{
  boost::function<int(int)> factorial = y(fact);
  std::cout << factorial(5) << std::endl;
  return 0;
}


Answer 2:

#include <functional>
#include <iostream>

template <typename Lamba, typename Type>
auto y (std::function<Type(Lamba, Type)> f) -> std::function<Type(Type)>
{
    return std::bind(f, std::bind(&y<Lamba, Type>, f), std::placeholders::_1);
}

int main(int argc,char** argv)
{
    std::cout << y < std::function<int(int)>, int> ([](std::function<int(int)> f, int x) {
        return x == 0 ? 1 : x * f(x - 1);
    }) (5) << std::endl;
    return 0;
}


Answer 3:

你能解释这一切是如何工作的?

FIX2设为y组合子(具体而言,它是带有两个参数的功能的组合子;第一个参数是函数(递归的目的),第二个参数是一个“正确”的函数的参数)。 它创建递归函数。

BLL :: RET(...)似乎创建一些形式的函数的对象,其中所述主体是

if(second arg == 0)
{
    return 1;
}
else
{
    return second arg * first arg(second arg - 1);
}

“懒”是有可能停止第一(功能)参数的无限扩大(阅读了关于懒惰和严格ÿ组合子之间的差别,看看为什么)。

该代码是相当可怕的。 匿名函数是不错的,但两轮牛车来解决C ++的缺少语法支持使他们不值得。



文章来源: Fixed point combinators in C++