« はじめに利権維持ありき | メイン | Code Geass: Lelouch of the Rebellion R2 #07 捨てられた仮面 »

F# における高階関数とカリー化

F# では関数を引数として取る関数や、関数を戻り値として返す関数を作ることができる。.NET Framework 上でどのようなアセンブリになっているのか関心があったので調べて見た。

まず、次のようなコードを定義する。

let add x y = x + y;;
let mul x y = x * y;;
let calc f =(f 2 3);;
let addx x = add x;;
Code 1

この場合、関数 add は 2 つの引数を取って足した結果を返す関数です。同様に関数 mul は掛け算した結果を返す関数です。さてでは、関数 calc と関数 addx は何なのか?

この場合、関数 calc は引数を 2 つ取る関数 f を引数として取り、関数 f に 2 と 3 という引数を与えて答えを返す関数です。つまり、先程の話では引数として関数を取る関数です。関数 addx はもっと、面白い挙動で、この場合引数を 1 つとって、関数 add の残りの引数を引数に持つ関数を返す関数です。計算機科学ではカリー化とも言います。

さて、F# でこれらができるのがわかったところで、コンパイルした結果のアセンブリがどのようになっているかを見てみます。まず、calc からです。

public static T calc(FastFunc<int  , FastFunc<int  ,T>> f)
{
	return FastFunc<int int ,>.InvokeFast2<t>(f, 2, 3);
}
Code 2

次に、addx です。

[Serializable]
internal class addx@4 : FastFunc<int, int>
{
    // Fields
    public int x@1;

// Methods
public addx@4(int x@1)
{
this.x@1 = x@1;
}

public override int Invoke(int y@1)
{
return Highorder.add(this.x@1, y@1);
}
}

public static FastFunc<int, int> addx(int x)
{
return new addx@4(x);
}


Code 3

上記の結果は、F# 1.9.3.14 のコンパイルの結果を .NET Reflector で C# で逆コンパイルしています。見ての通り、calc はある程度想定したとおりですが。addx は 一つのパラメータでインスタンス化した Invoke というメソッドを持つ関数を返す構造になっています。

関数の参照は delegate という形で簡単に表現できますが、関数を返すにはオブジェクトなどの形になっていないと面倒なことになるのでこういう形になったのでしょう。理屈の上では .NET Framework 3.5 以上ではラムダ式とかも使えるはずですが。関数が完全にファーストクラスオブジェクトというわけではないですからね。ラムダ式自体にも制約がありますし、なんでもできるわけではないですから。



Foundations of F# (Expert's Voice in .Net) Foundations of F# (Expert's Voice in .Net)


Robert Pickering



Apress 2007-05-28


売り上げランキング : 24771



Amazonで詳しく見る
by G-Tools

Technorati のタグ: ,
このエントリーをはてなブックマークに追加 Save This Page to del.icio.us このエントリーをlivedoorクリップに追加 このエントリーをニフティクリップに追加 このエントリーをBuzzurlに追加このエントリーをBuzzurlに追加 このエントリーをFC2ブックマークへ追加 このエントリーをnewsingへ追加 このエントリーをYahoo!ブックマークに追加

トラックバック

このエントリーのトラックバックURL:
http://www.cworld2000.com/cgi-bin/mt/mt-tb.cgi/413

コメントを投稿

(いままで、ここでコメントしたことがないときは、コメントを表示する前にこのブログのオーナーの承認が必要になることがあります。承認されるまではコメントは表示されません。そのときはしばらく待ってください。)

About

2008年05月07日 22:36に投稿されたエントリーのページです。

ひとつ前の投稿は「はじめに利権維持ありき」です。

次の投稿は「Code Geass: Lelouch of the Rebellion R2 #07 捨てられた仮面」です。

他にも多くのエントリーがあります。メインページアーカイブページも見てください。

検索

この Weblog について

Creative Commons License
このブログは、次のライセンスで保護されています。 クリエイティブ・コモンズ・ライセンス.
Powered by
Movable Type 3.35