代码之家  ›  专栏  ›  技术社区  ›  1800 INFORMATION

C++中的定点组合器

  •  7
  • 1800 INFORMATION  · 技术社区  · 17 年前

    我对使用定点组合器的实际示例很感兴趣(例如 y-combinator 在C++中。你用过固定点组合器吗? egg bind 在真实的代码中?

    我在鸡蛋里发现这个例子有点浓:

    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);
    }
    

    你能解释一下这一切是如何运作的吗?

    是否有一个很好的简单示例,可能使用的bind依赖性比这个要少?

    3 回复  |  直到 9 年前
        1
  •  30
  •   Andy Prowl    13 年前

    这是转换成 boost::bind 注意,y-combinator及其在主函数中的应用站点。我希望这有帮助。

    #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;
    }
    
        2
  •  8
  •   matthewtff    13 年前
    #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;
    }
    
        3
  •  3
  •   DrPizza    17 年前

    你能解释一下这一切是如何运作的吗?

    fix2是一个y组合器(具体来说,它是两个参数的函数的组合器;第一个参数是函数(为了递归的目的),第二个参数是“合适的”函数参数)。它创建递归函数。

    BLL::RET(…)似乎创建了某种形式的函数对象,其主体是

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

    “lazy”大概是为了阻止第一个(函数)参数的无限扩展(请阅读lazy和严格的y组合器之间的区别以了解原因)。

    代码非常可怕。匿名函数是很好的,但是在C++缺乏句法支持的情况下的黑客行为使它们不值得付出努力。