Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Anonymous Recursion in C++

Anonymous Recursion in C++

C++で無名再帰を行う
source code: https://gist.github.com/na-o-ys/56434282baa5705efe7e3bd05e3f04d1

na-o-ys

May 19, 2016
Tweet

More Decks by na-o-ys

Other Decks in Programming

Transcript

  1. ී௨ͷ࠶ؼ (ϑΟϘφον਺) #include <iostream> int fib(int n) { return n

    <= 1 ? 1 : fib(n-1) + fib(n-2); } int main(int argc, char const* argv[]) { std::cout << fib(4) << std::endl; return 0; }
  2. ೰Έ #include <iostream> int fib(int n) { return n <=

    1 ? 1 : fib(n-1) + fib(n-2); } int main(int argc, char const* argv[]) { std::cout << fib(4) << std::endl; return 0; } ͜͜Ͱ͔͠࢖Θͳ͍ͷʹ ͍͍ͪͪؔ਺ఆٛ͠ͳ͖Ό͍͚ͳ͍
  3. ϥϜμͰॻ͍ͯΈΔ #include <iostream> int main(int argc, char const* argv[]) {

    std::cout << ([](int n) -> int { return n <= 1 ? 1 : fib(n-1) + fib(n-2); })(4) << std::endl; return 0; } ※ίϯύΠϧͰ͖·ͤΜ
  4. ໰୊఺ #include <iostream> int main(int argc, char const* argv[]) {

    std::cout << ([](int n) -> int { return n <= 1 ? 1 : fib(n-1) + fib(n-2); })(4) << std::endl; return 0; } ໊લ͕ແ͍ͷͰࣗ෼ࣗ਎Λݺ΂ͳ͍ = ࠶ؼͰ͖ͳ͍ʂ
  5. 1. Ҿ਺ʹࣗ෼ࣗ਎Λड͚औΔ ϥϜμΛॻ͍ͯ [](auto self, int n) -> int {

    return n <= 1 ? 1 : self(n-1) + self(n-2); } ࣗ෼ࣗ਎ ※Ҿ਺ͷܕʹ auto Λࢦఆͨ͠ϥϜμ͸ɺςϯϓϨʔτؔ਺ΦϒδΣΫτͱͯ͠ ѻΘΕΔ(generic lambda: C++14 Ͱ௥Ճ)
  6. 2. ෆಈ఺ίϯϏωʔλʹ৯ΘͤΔ // 不動点コンビネータを作る template<typename Func> struct fixed { Func

    f; template<typename... Args> auto operator()(Args... args) { return f(fix(f), args...); } }; template<typename Func> fixed<Func> fix(Func f) { return fixed<Func> { f }; } ~~~~~~ // 食わせる fix( [](auto self, int n) -> int { return n <= 1 ? 1 : self(n-1) + self(n-2); } )
  7. ಈ͘ʂ #include <iostream> // 省略 int main(int argc, char const*

    argv[]) { std::cout << (fix( [](auto self, int n) -> int { return n <= 1 ? 1 : self(n-1) + self(n-2); } ))(4) << std::endl; return 0; } $ g++-6 -std=c++1y sample.cpp $ ./a.out > 5
  8. GCD (࠷খެഒ਺) ͱ͔ • ࠶ؼͰॻ͚͹ҰߦͰࡁΉ΍ͭ #include <iostream> // 省略 int

    main(int argc, char const* argv[]) { std::cout << (fix( [](auto self, int a, int b) -> int { return b == 0 ? a : self(b, a % b); } ))(15, 9) << std::endl; return 0; } $ g++-6 -std=c++1y sample.cpp $ ./a.out > 3
  9. ෆಈ఺ίϯϏωʔλ • ఆٛ: fix(f)(args) = f(fix(f), args) • ্ࣜΛͣͬͱோΊͯΔͱɺಈ͘ཧ༝͕ݟ͑ͯ ͖·͢

    • ώϯτ • ӈล f: ఆٛͨ͠ϥϜμࣜ • f(self, args) • ࠨล fix(f): argsͷΈΛड͚औΔؔ਺ • = self template<typename Func> struct fixed { Func f; template<typename... Args> auto operator()(Args... args) { return f(fix(f), args...); } }; template<typename Func> fixed<Func> fix(Func f) { return fixed<Func> { f }; }