|
2.2.5 純関数

純関数の定義
Nestや Map等の関数操作が使われるとき,適用される関数は必ず指定されなければならない.これまでに示した例では,関数の「名前」を明記することでこれを行ってきた.純関数と呼ばれる式の構成形式を使うことで,関数名を宣言しなくても,引数に適用させることができる関数を定義することができる.
関数 hを定義する.
In[1]:= h[x_] := f[x] + g[x]
hは,すでに定義済みなので Mapで直接使 うことができる.
In[2]:= Map[h, {a, b, c}]
Out[2]= 
このように純関数を使っても同じ結果を得ることができる.
In[3]:= Map[ f[#] + g[#] &, {a, b, c} ]
Out[3]= 
純関数を宣言する方法がいくつか用意されている.どの方法を使おうが基本的な考えは,適切な引数が与えられるときに特定の関数を計算してくれるオブジェクトを構築することにある.例えば,funが純関数なら,fun[a]は,aを引数としこの関数を評価する.
xの2乗を取る操作を表した純関数を定義する.
In[4]:= Function[x, x^2]
Out[4]= 
定義した純関数に引数nを与えると,nの2乗の答が返されてくる.
In[5]:= %[n]
Out[5]= 
純関数は,通常の名前付き関数が使えるところであれば同様に使うことができる.
純関数を Map式の中で使うこともできる.
In[6]:= Map[ Function[x, x^2], a + b + c ]
Out[6]= 
Nestでも使うことができる.
In[7]:= Nest[ Function[q, 1/(1+q)], x, 3 ]
Out[7]= 
2引数の純関数を定義し,この関数を引数 aおよび bに適用する.
In[8]:= Function[{x, y}, x^2 + y^3] [a, b]
Out[8]= 
関数を繰り返し使う場合は,f[x_] := bodyの書式で関数を定義し,関数の参照はその名前f で行った方がよいだろう.しかし,関数を一度しか使わない場合は,関数をどう呼ぶかを考える必要がない純関数の形で関数を定義した方がよいだろう.
形式論理やLISPプログラミング言語に精通した読者なら, Mathematicaの純関数が 文や,匿名関数に相当したものだと気が付いたかもしれない.また,純関数は,演算子に関する純粋に数学的な考えに近いものでもある.

純関数で使われる短縮形
関数を繰り返し使わなければ名前を付けてもあまり意味がないように,純関数の引数に名前を付けてもあまり意味がない. Mathematicaでは,純関数を記述する際,特に引数に名前を付けなくてもよいようになっている.名前の代りに,#nの書式で引数の位置を指定するだけでよい.純関数では,#nは,n番目に与える引数を指す.#だけだと第1引数を意味する.
#^2 &は,引数の2乗を計算するための,短縮形で書かれた純関数である.
In[9]:= Map[ #^2 &, a + b + c ]
Out[9]= 
各リストから最初の2要素を抽出する関数を適用する.純関数を使ったので,関数を繰り返し定義する必要がなくなる.
In[10]:= Map[Take[#, 2]&, {{2, 1, 7}, {4, 1, 5}, {3, 1, 2}}]
Out[10]= 
fromdigitsは,1度 2.2.2で構築したが,短縮形で記述するとさらに簡単な形にすることができる.
In[11]:= fromdigits[digits_] := Fold[(10 #1 + #2)&, 0, digits]
短縮形で純関数を構築するときは,式の末尾にアンド記号(&)を付けることを忘れないようにする.この記号がないと,式は純関数として認識されなくなってしまう.
アンド記号の短縮形を使う際に注意する点として,式のまとめ方がある.A.2.7で示すように,アンド記号はどちらかというと低い優先順位を持つ.このため,例えば, #1 + #2 &のような式は,カッコなしで記述することができる.その反面,書式 option ->(fun &)を使い,純関数全体を変換規則の一部として使うときはカッコがないと問題になる.
純関数は,引数をいくつでも取ることができる.##を使うことで,与えられるすべての引数を表すことができる.また,##nは, n番目以上のすべての引数を表す.
##は,すべての引数を表してくれる.
In[12]:= f[##, ##]& [x, y]
Out[12]= 
##2は,最初を除いた全引数を表す.
In[13]:= Apply[f[##2, #1]&, {{a, b, c}, {ap, bp}}, {1}]
Out[13]= 
|