Mathematicaで関数をカリー化

Mathematicaで関数をカリー化してみます。

まず、2つの引数を足し合わせるadd1関数を、普通に定義してみます。Mathematicaで一般的に関数を定義するには、このような形式で書くことが多いと思います。

In[1]:= add1[x_, y_] := x + y

この関数を呼んでみましょう。

In[2]:= add1[3, 4]
Out[2]= 7

問題ありませんね。
次に、これを匿名関数を使って書き換えてみるとどうなるでしょうか。匿名関数は、Function[]関数を使って定義します。関数名は、add2とします。

In[3]:= add2 = Function[{x, y}, x + y]
Out[3]= Function[{x, y}, x + y]

ここまでは大丈夫でしょう。Function[]関数は、第一引数に、匿名関数の引数のリスト、第二引数に、匿名関数の本体(body)を記述しました。念のため定義した関数を呼んでみます。

In[4]:= add2[5, 6]
Out[4]= 11

ちゃんと動作していますね。
ちなみに、Mathematicaの匿名関数は、Function[]を使わずに、#と&の演算子を用いて定義することもできます。こちらのほうがタイピング量が少なく、簡潔ですので、関数を必要とするMap[]関数などの引数に使うことが多いです。そのバージョンのadd3を書いてみると、

In[5]:= add3 = (#1 + #2 ) &
Out[5]= #1 + #2 &

このように書けます。これはこれで便利なのですが、今回のテーマはカリー化です。カリー化をするにはこの書き方では出来ないので、先に示したFunction[]による匿名関数を使います。

さて、2引数の関数をカリー化すると、1引数を受け取って「1引数を受け取って結果を返す関数」を返す、となります。したがって、Function[]定義の中にもう一段Function[]が入ることになります。
まず、外側のFunctionは、1引数を受け取るのでその第一引数は x とします。その第二引数には Function[ ] が入ります。内側のFunctionは、引数を1つ受け取ります。これを y とします。最後に、内側のFunctionのbodyに、各引数の和 x + y を書けば完成となります。

In[6]:= add4 = Function[x, Function[y, x + y]]
Out[6]= Function[x, Function[y, x + y]]

流れに従って、add4を定義しました。
add4のシグネチャを見ると、1引数関数です(そのように設計したので当たり前ではありますが…)。まずは、add4に1つ引数を渡して何が返るか見てみると、

In[7]:= add4[7]
Out[7]= Function[y$, 7 + y$]

このように返ってきました。add4に7を渡したことで、「1引数を受け取って、7にそれを足した結果を返す関数」が返っています。正しくカリー化できています。
そういうわけで、add4を機能させるには、add4[7, 8]と呼ぶのではなく、次のように add4[7][8] と呼ぶ必要があります。

In[8]:= add4[7][8]
Out[8]= 15

確かに、2つの数を足した結果を返していることが分かり、関数が機能していることが分かったと思います。
カリー化は関数呼び出しの1つの方法なので、普段Mathematicaを使用する上では全く意識する必要はありませんが、定義の仕方によってはそれっぽいものができることが分かりました。

いいなと思ったら応援しよう!