それを自動的に行う方法があります。関数を考えてみましょう
f[a_, b_, c_] := {a, b, c}
暗黙的に「カレー可能」にしたいので、次のいずれかの方法で呼び出すことができます。
f[1, 2, 3]
f[1, 2][3]
f[1][2][3]
これは、次の定義を自動的に生成する方法がある場合に実現できます(以下で行います)。
f[a_, b_, c_] := {a, b, c}
f[a_, b_] := Function[c, f[a, b, c]]
f[a_] := Function[b, Function[c, f[a, b, c]]]
上記の他のMattの回答と同様に、f:= Funcion [a、Function [b、Function [c、BODY]]]という1つの定義しか実行できませんでしたが、f[を介してfを呼び出すことはできません。 a、b、c]またはf [a、b]であり、f[a][b]またはf[a][b][c]としてのみ呼び出す必要があります。複数の定義があるため、どちらのスタイルも選択できます。
これらの定義の生成は、関数(以下で定義)CurryableSetDelayedを呼び出すだけで実行できます。
CurryableSetDelayed[f[a_, b_, c_], {a, b, c}]
これは、SetDelayedが機能するのと同じように、これらのシンボルのいずれかが定義されている場合でも、期待どおりに機能します。
また、表記パッケージを使用すると、代入演算子として表示させることができます。f [a_、b_、c]#= {c、b、a}と言いますが、私は試しませんでした。
以下のソースでは、セッションと競合する可能性のあるいくつかのアドホックシンボルを使用しているため、これを使用する場合は、パッケージの名前空間で囲んでください。
完全なコード:
ClearAll[UnPattern];
ClearAll[MakeFunction]
ClearAll[CurriedDefinitions]
ClearAll[MyHold]
ClearAll[MyHold2]
ClearAll[CurryableSetDelayed]
SetAttributes[UnPattern,HoldAllComplete];
SetAttributes[MakeFunction,HoldAllComplete];
SetAttributes[CurriedDefinitions,HoldAllComplete]
SetAttributes[MyHold,HoldAllComplete]
SetAttributes[MyHold2,HoldAllComplete]
SetAttributes[CurryableSetDelayed,HoldAllComplete]
UnPattern[x_]:=Block[{pattern},MyHold[x]/. Pattern->pattern/. pattern[v_,_]:>v]
MakeFunction[param_,body_,attrs_]:=With[{p=UnPattern[param],b=UnPattern[body]},
Block[{function},MyHold[function[p,b,attrs]]/. function->Function]]
CurriedDefinitions[fname_[args__],body_,attrs_]:=MapThread[MyHold2[#1:=#2]&,
{Rest[(MyHold[fname]@@#1&)/@NestList[Drop[#1,-1]&,{args},Length[{args}]-1]],
Rest[FoldList[MakeFunction[#2,MyHold[#1],Evaluate[attrs]]&,MyHold[fname[args]],
Reverse[Drop[{args},1]]]]}]
CurryableSetDelayed[fname_[args__],body_]:={MyHold2[fname[args]:=body],
Sequence@@CurriedDefinitions[fname[args],body,Attributes[fname]]}
//. MyHold[x_]:>x/. MyHold2[x_]:>x
更新、属性(HoldAllCompleteなど)がすべてのパラメーターに拡張されるようになったため、 CurryableSetDelayedを呼び出す前に属性を設定する限り、以下は期待どおりに機能します。
In[1185]:= ClearAll[f];
SetAttributes[f, {HoldAllComplete}]
CurryableSetDelayed[
f[a_, b_, c_], {ToString@Unevaluated@a, ToString@Unevaluated@b,
Unevaluated@c, Hold@c}];
f[1 + 1, 2 + 2, c + 1]
f[1 + 1, 2 + 2][c + 1]
f[1 + 1][2 + 2][c + 1]
Out[1188]= {"1 + 1", "2 + 2", Unevaluated[c + 1], Hold[c + 1]}
Out[1189]= {"1 + 1", "2 + 2", Unevaluated[c + 1], Hold[c + 1]}
Out[1190]= {"1 + 1", "2 + 2", Unevaluated[c + 1], Hold[c + 1]}