編集可能

カリー化と部分適用の違いと誤用

まとめました。
51
Kota Mizushima (on a diet) @kmizu

正直に言うと、Groovy自体は別に好きでも嫌いでもないのだけど、カリー化してないのにcurryとかいうメソッド名付けてたり(標準で)、概念の無理解が目立つ部分があって、その辺がちょっと…という思いがあったり。 #scalajp #groovy

2011-09-04 19:43:37
ふも @fumokmm

@kmizu 本当のカリー化とどう違うんでしたっけ?

2011-09-04 19:55:10
Kota Mizushima (on a diet) @kmizu

@fumokmm Groovyのアレは概念としては「部分適用」とかそう呼ばれるものになります。ちょっと次から違いを説明します。ちょっとわかりやすくするために型な話になります。 #groovy

2011-09-04 20:01:33
ふも @fumokmm

@kmizu なるほど、部分適用の方ですか。ちょっと私も勉強してみますね。ありがとうございます。

2011-09-04 20:02:40
Kota Mizushima (on a diet) @kmizu

@fumokmm で、Groovyのcurryって、 add = { x, y -> return x * y }; add.curry(2) とかいう風に使うわけですが、これはどう見てもカリー化じゃなくて部分適用だろ、とツッコミたくなるわけです。 #groovy

2011-09-04 20:06:43
ふも @fumokmm

@kmizu ですね、部分適用ですね。ちなみに add.curry(2) ってした場合、戻りの型は CurriedClosure という痛い名前になってますw

2011-09-04 20:09:28
Ryo Asai @ryoasai74

これも部分適用をcurryと称している例では。 / Prototype JavaScript framework: Function.curry http://t.co/7KLIBpG

2011-09-04 20:29:01
Ryo Asai @ryoasai74

ちなみに、Clojureでは部分適用は正確にpartial関数と呼ばれていたと思います。

2011-09-04 20:30:18
Ryo Asai @ryoasai74

The joy of clojureのP127に以下の説明があるのですが、これは正確なのかな。The use of partial differs from the notion of currying in a fundamental way...

2011-09-04 20:32:31
Ryo Asai @ryoasai74

A function built with partial will attempt to evaluate whenever it's given another argument...

2011-09-04 20:33:46
Ryo Asai @ryoasai74

A curried function on the other hand will return another curried function until it receives a pre-determined number of arguments ...

2011-09-04 20:34:42
Ryo Asai @ryoasai74

--- only then will it evaluate. Because Clojure allows functions of variable number of arguments, currying makes little sense.

2011-09-04 20:35:54
Ryo Asai @ryoasai74

つまり、3個の引数を取る関数をカリー化したものに1個の引数で呼び出すと直ちに評価されずに2個引数をとる別の関数が得られる。部分適用だと直ちに評価されてしまう。

2011-09-04 20:38:22
Ryo Asai @ryoasai74

誤用が広まって市民権を得るということもあるので、部分適用を一部の言語ではカリー化と呼ぶのは方言の一種ということでよいのではないでしょうかね。実際、プログラミングの世界ではよくあることに思われます。

2011-09-04 20:40:26
ゆとり @megascus

部分適用って言葉があるのか。コンストラクタで一部の引数をとって、他の引数はメソッドで渡すって感じかなぁ。

2011-09-04 20:44:04
Shingo Omura @everpeace

@ryoasai74 僕、それよくないと思います。使うならバウンデッドコンテキストを意識して利用してほしいです。groovy 界隈だけじゃないですか?その誤用って。他の昔からある関数型言語ではカリー化と部分適用をごっちゃにしてるのは少ない【気がします】が。

2011-09-04 20:44:06
Ryo Asai @ryoasai74

@everpeace 先に上げたJSのprototype.jsの例のように動的言語のコンテキストでは結構ごっちゃになって使われているようです。 http://t.co/ZwdNbg9

2011-09-04 20:46:43
Shingo Omura @everpeace

でも、カリー化自体に、引数の束縛という動作は関係ない概念なのに、どこのだれが、部分適用とカリー化をごっちゃに言い出したんだろう?そもそも混用される概念じゃないと思うが。。。

2011-09-04 20:46:44
ゆとり @megascus

@ryoasai74 boostのドキュメントを読むと、カリー化(第一引数のみ)を一般化したものが部分適用みたく見えますけれども、違うものなのでしょうか。 http://t.co/RTccJvS

2011-09-04 20:52:18
Ryo Asai @ryoasai74

この説明だと部分適用との違いがよくわからない? / カリー化 - Wikipedia http://t.co/WbHYJ5o

2011-09-04 20:52:35
GLAD!! @glad2121

@ryoasai74 何の文脈で話をしてるのか分かりませんが、「部分適用だと直ちに評価されてしまう」の意味がよく分かりません。f(x,y,x)=x+y+z に x=2 を部分適用すれば、g(y,z)=2+y+z となり、y,z は評価されないと思いますが。

2011-09-04 20:52:47
Shingo Omura @everpeace

@ryoasai74 そうなんですか。完全な誤用ですね。。。。こんなん市民権得てたら怖いですね。カリー化は束縛なんて関係ない関数の型の話なのに。

2011-09-04 20:54:35
Ryo Asai @ryoasai74

Currying - Wikipedia, the free encyclopedia http://t.co/BkmtIVa

2011-09-04 20:54:41
GLAD!! @glad2121

@everpeace が先に突っ込んでた…。(^^;)

2011-09-04 20:54:45
Ryo Asai @ryoasai74

The Uncarved Blog: Partial Function Application is not Currying http://t.co/c9L1bkQ

2011-09-04 20:55:14
残りを読む(89)

コメント

watcher @a_watcher 2011年9月5日
うーん、知らない人がこれ読んでも何もクリアにならない予感。140文字でまとめようよ。「curry化=複数引数の関数f(x,y,z)と最初の実引数Xをとり、二番目以降の引数をとる関数f'(y,z)を返す。部分適用=複数引数の関数f(x,y,z)の一部引数に実引数を束縛(例えばx=X,y=Y)した関数f'(z)≡f(x=X,y=Y,z)を返す。相違は引数の適用順」で問題あるのかなぁ。
0
山宮隆 @propella 2011年9月5日
@a_watcher これはややこしい。@everpeace さんのおっしゃるとおり、カリー化には適用が含まれないので適用の順序は関係ないんじゃないですか?
0
山宮隆 @propella 2011年9月5日
しかし、私も最近まで部分適用の事をカリー化と思っていた。私がカリー化だと思っていた操作は部分適用で、Haskell の curry や uncurry 関数は逆に違和感があった。カリー化がインパクトありすぎてドキュメントの中で部分適用という言葉を使わなさすぎなのでは。
0
山宮隆 @propella 2011年9月5日
あと、さすがに動的言語でも関数の作成と適用は別の概念なので、動的言語だからごっちゃになるわけなくて、たまたまでしょう。
0
Kota Mizushima (on a diet) @kmizu 2011年9月5日
短くまとめるのはいいのですが、「curry化=複数引数の関数f(x,y,z)と最初の実引数Xをとり、二番目以降の引数をとる関数f'(y,z)を返す。」ここがダウトです。最初の実引数は無関係で、「複数引数の関数f(x,y,z)を取り、関数f`=(fn(x) fn(y) fn(x) ...)を返す。」辺りでしょうか。
0
watcher @a_watcher 2011年9月5日
@kmizu うーん、関数fの引数をn個として、curry化をn回行えば1引数の関数n個の合成のような形に表現できるけど、普通は私の先の定義で充分でしょう。「ダウト」と宣言するような話ではない。
0
ふも @fumokmm 2011年9月5日
Groovyで本当のカリー化をしてみたブログへのリンクのつぶやきを追加しました。
0
watcher @a_watcher 2011年9月5日
kmizuさんの個別mentionによるご指摘その他に基づき訂正。「Curry化の例:関数f(x,y,z)をとり、引数を一個ずつとる高階関数g = (\x ->(\y ->(\z ->f(x,y,z))))を返す。部分適用の例:関数f(x,y,z)の一部引数に実引数を束縛(例えばx=X,y=Y)した関数h(z)≡f(x=X,y=Y,z)を返す。」「前者にはおそらく厳密な定義があり(要確認)、引数の適用順番に縛りがある。後者はより広範な概念で、引数の適用順番に必ずしも縛りがない」
0
watcher @a_watcher 2011年9月5日
って、everpeaceさんtweetで言いつくされていますよね。http://twitter.com/everpeace/status/110320382925475841 (一応最初から認識はしていたけど)
0
たかぎ @tkghs 2012年8月14日
add.curry(2) は (add.curry)(2) と add.(curry(2)) のどっちなの?
0