カリー化 (currying) とは、計算機科学分野の技法の一つ。複数の引数をとる関数を、引数が「もとの関数の最初の引数」で戻り値が「もとの関数の残りの引数を取り結果を返す関数」であるような関数にすること。
2013-05-24 16:05:16@wraith13 複数引数をタプルで実現しているとして、複素数をタプルで実現したとすると、複素数を一つとる関数はカリー化すると実部と虚部がばらけるとかそんな感じでは。カウントというのを理解できてないのでなんか違うこと言ってるかもしれません
2013-05-24 16:17:32@wraith13 型付き前提だとして、a型とb型を取ってc型を返す関数fがあったとすると、それをa型を取って「b型を取ってc型を返す関数」を返す関数にするのがカリー化で、タプルはコンパイル時に要素が分かるのでそれと同じ考えでばらせます。が、配列は分からないのでばらせません。
2013-05-24 16:25:32長さが型レベルに現われている配列(それはタプルと何が違うのだ?)ならカリー化したら要素を一個ずつ引数に取れますね
2013-05-24 16:27:21@decimalbloat @bleis やっぱり本来のカリー化の理屈的には必ずプライマリーな要素毎にぶった切る・・・ってところですかね。
2013-05-24 16:29:01@wraith13 タプルを*で表すとして、(a*b)*c->dな関数をカリー化関数(t*u->v)->t->u->vに渡すと、(a*b)->c->dになるので、プライマリーがどうとかはたぶん関係ないです
2013-05-24 16:33:23カリー化は「いつでも必ずしなきゃいけない」様なものではないから、構造体とか複素数みたいな「ひとつの概念としてまるっと扱う」ことが重要なものの構成要素をわざわざバラして扱う必要はないと理解してます。
2013-05-24 16:35:22@bleis 突き詰めちゃうと bool 値になっちゃうし、形として引数が一つになっていることが重要なんであって、なにをもってとして引数が一つになっていると見なすかってところは好きにしろってところなんですかね。
2013-05-24 16:36:22@wraith13 @bleis その言語体系のなかで1つの値なんであれば、それはそれでいいんじゃないですかね。ただ、たとえば2つの引数a,bをとる関数を、aとbが格納されたひとつの配列をうけとる関数にするというのは、関数の変換ではなく値の変換なのでカリー化ではない、となるかと
2013-05-24 16:37:37いわゆる手続き型言語の2引数関数をいわゆる関数型言語で実現すると、同時に1引数として受け取るかカリー化で高階関数にするかどっちかになるだろうけど、それは場合によるでしょう。前者を選んだときに、タプルが便利であればタプルにするだろうけど、構造体とかオブジェクトの形でもいいわけで。
2013-05-24 16:41:09@wraith13 もともとのラムダ計算の話でいえば、値なんかなくて全部関数なので、なにをひとつの値とするかって話はあまり関係なくなると思います。z()という関数が0を表すとして、succ(z())が1、succ(succ(z())が2、みたいな、関数適用ですべての値を表す感じ
2013-05-24 16:47:52@kis あら。全然、別の話で個人的に進めてるプロジェクトで数の定義をどうするか?ってので同じようなところへ着地しつつあります。。。 > z()という関数が0を表すとして、succ(z())が1、succ(succ(z())が2、みたいな
2013-05-24 16:54:07