Help us understand the problem. What is going on with this article?

Python : lambdaの中でも再帰できた

More than 1 year has passed since last update.

参考にした記事:Fizz Buzz問題で副作用と代入を抑えてみる【JavaScript、VB.Net、Python3、CommonLisp、Clojure、HSP、R言語】のコメント
Pythonでのワンライナー:再帰
Yコンビネータなんて複雑なものを作らなくても、関数に自分自身を受け取る引数があればいいのです。

lambdaの中に再帰は書けない(特別なことをしない限り)と思ってたんですけど、できるんですね。知らんかった。
いや、以前は読んでも理解できなくて脳内スルーしてたんだと思う。

記事を参考に自分でも階乗を書いてみました。

do = pack_to_tuple = lambda *x : x
case = unpack_and_evaluate_in_order_then_return_last = lambda x : x[-1]
otherwise = True

f = ( lambda x :
        case(     x == 0   and do( 1 )
              or otherwise and do( x * f( x - 1 ) )
             )
    )

f2 = ( lambda x :
       ( lambda f : f( f,  x ) ) ( lambda f, x :
                                     case(     x == 0   and do( 1 )
                                           or otherwise and do( x * f(f,  x - 1 ) )
                                         )
                                 )
     )

print(f(10), f2(10))
# 結果
3628800 3628800

※ 最初の三行は、Haskellっぽくガードっぽい条件分岐をするためのものです。
できた!

上の関数fと下の関数f2と同じ事をしています。
上の方は普通に再帰してます。こっちは普段やってるし理解できる。
下の方は?ちょっと難しい...
無名再帰で階乗を返す関数を作って、f2という名前をつけている、って感じでしょうか?

  • x と f を引数とし f(f,x) を返り値とする無名関数の引数 f に、
  • f と x を引数とし、x の値によって 1 または x*f(f,x-1) を返す無名関数を渡す
  • x を引数とする無名関数

何となくわかるようなわからないような...でも、上から下に機械的に変換することはできるので、必要になったときにはなんとかなりそうです。

違うよ、とか、こういうことだよ、とかあればコメントお願いします。

追記 これでいいのか

参考記事:【Python】lambdaで再帰

キーワード引数を使うと...

f3 = ( lambda x, f =  lambda f, x : case(     x == 0   and do( 1 )
                                        or otherwise and do( x * f(f,  x - 1 ) )
                                    )
       : f( f,  x ) 
     )

すっきり。何となく意味もわかりやすいような。勉強になりました。

Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away