読者です 読者をやめる 読者になる 読者になる

Pythonでカリー化と部分適用について考えてみる

まず前提として、ちゃんと学ぶなら自動カリー化をサポートしてるhaskellなりOCamlなりF#なりで学ぶほうが断然いいと思います。

カリー化TLだったので

自分の理解が正しいかどうか再確認。

# こういう関数があるとする
def multiply(x, y):
    return x * y

# これがカリー化
curried_multiply = lambda x: lambda y: x * y
print curried_multiply(2)(3) #-> 6

# lambda使わないならこう
def curried_multiply_d(x):
    def _curried_multiply_d(y):
        return x * y
    return _curried_multiply_d

print curried_multiply_d(2)(3) #-> 6

# こっちが部分適用
from functools import partial

partial_applied_multiply = partial(multiply, 2)
print partial_applied_multiply(3) #-> 6

ふと思ったこと

hoge = curried_multiply(2)
fuga = partial(multiply, 2)

このhogeとfugaがすごく似たような状態になっているので紛らわしいのかも
ちなみにこの状態はどちらも部分適用で

  • hogeはカリー化関数に部分適用した状態
  • fugaは非カリー化関数に部分適用した状態

という理解でいいのかな?

※追記
そもそもいわゆるカリー化がデフォルトであるHaskellみたいな言語から見ると、複数の引数を要求する関数はカリーではないので「非カリー化した」関数であると言える。逆に複数引数を扱うのが一般的な言語からみたら、一引数関数の連鎖に書き換える行為を「カリー化」と呼ぶと言える。

なので、同じ視点から「こっちはカリー化、こっちは非カリー化」というのはちょっとおかしい。また、カリー化関数は一引数なので部分適用するというのはちょっと語弊がある。連鎖したカリー化関数の一部の関数の引数に値を割り当てた状態、とでも言えばいいのかな。

というわけで

ツッコミお待ちしております!

おまけ

Python関数型プログラミングを学んでみたい!って人は
Functional Programming HOWTO — Python v2.7.3 documentation(英語)
関数型プログラミング HOWTO — Python 2.7ja1 documentation(↑の日本語訳。
ただしPython2.6)
魅力的なPython: Pythonでの関数プログラミング: 第1回
辺りを読んでみるといいかも

あと、PyPIにfunctionalっていうライブラリが転がってます。
functional 0.7.0 : Python Package Index

functional.compose(func1, func2)

ていう感じで関数合成なんかもできちゃいます。