SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

DeveloperZine(デベロッパージン)- エンジニアの意思決定を支える技術情報メディア ProductZine

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

C#プログラマのためのF#入門

関数型言語としてのF#

C#プログラマのためのF#入門(2)

カリー化

 高階関数のところで紹介しましたが、F#では関数を引数としたり、戻り値とすることができます。そこで、引数が複数ある関数を、「1つ目のパラメーターを引数とし、「2つ目以降のパラメーターを引数とする関数」を返す関数」にすることを「カリー化」と言います。

 例えば、下の例はxとyをパラメーターとして受け取り、x+yを返す関数testaddの定義ですが、この関数は下記のようにカリー化できます。

[リスト16]
//カリー前
let testadd x y = x + y
↓
//カリー化した後
let testadd = (fun x -> (fun y -> x + y) )

 カリー化を用いずパラメーターを組(タプル)として扱う場合は、F#Interactiveからの戻りが下記のように異なります。

[リスト17]組(タプル)を使用する
let addtesttest (x, y) = x + y ;;

 ▼

val addtesttest : int * int -> int  //“int * int”の部分に注目

 組を使用しない限り、F#では自動でカリー化が行われることが分かります。

[リスト18]カリー化が自動的に行われている
let addtesttest x y = x + y ;;

 ▼

val addtesttest : int -> int -> int  //“1つ目のint -> int”の部分に注目

 カリー化を行うことで、オリジナルの関数は1引数(パラメーター)を受け取るラムダ式あるいは、ネストされた複数のラムダ式に変換されます。

 カリー化のメリットとして、引数が1つになることから関数の合成が簡単になる傾向があることや、次に紹介する「部分適用」が可能になることなどがあげられます。

 C#でのカリー化を下記に、参考まで示しておきます。

[リスト19]C#でカリー化
//カリー化する前
  Func<int, int, int> f = (x, y) => x + y;
//カリー化後
  Func<int, Func<int, int>> f = x => y => x + y;

部分適用

 カリー化を利用して、下記のように、「部分適用」と呼ばれる機能を使用することが可能になります。

 このように、関数をカリー化して、1つめのパラメーター、もしくは、複数のパラメーター(全体で必要な引数より少ない数の引数)に定数値ををあらかじめバインドしてしまい、残りのパラメーターのみを受け取る中間関数のような関数を作成することを部分適用と言います。リスト20のように一定の値をインクリメントしたいときなどに使用すると便利な機能です。

[リスト20]部分適用
//部分適用
//パラメーターを2つとる関数Addの定義
let Add x y = x + y ;;
//パラメーターを1つだけ与えてみる
Add 1 ;;

 ▼

val Add : int -> int -> int

val it : (int -> int) = <fun:it@4>
 //int型のパラメータを受け取りint型の値を返す関数it(仮の名前)が返される。つまりit は  (fun y -> 1 + y)である。
[リスト21]itにパラメーターとして10を与えて実行してみる。
> it 10 ;;

 ▼

1+10が実行される
val it : int = 11

 Addはxとyをパラメーターとし、x+yを返す関数です。このAddにパラメーターを1つだけ与えて実行してみると、関数Addは自動的にカリー化されて、(fun 1 -> (fun y -> 1 + y) )になります。このとき、このネストされたラムダ式にitという仮の名前が与えられ、返されます。itにパラメータとして、10を与えると 1+10が実行されます。

演算子

 さて、ここまで、F#のいろいろな関数について解説してきましたが、F#では実は中置演算子も1つの関数です。中置演算子とは、引数に囲まれる形で配置され、前後の2つの引数から1つの結果を得る演算子のことです。例えば、"5+2=7"この式においては、"+"は中置演算子として機能しています。

 F#Interactiveで下記のように実行すると、+という中置演算子がint型のパラメーターを2つ受け取りintを返す関数であることが分かります。

[リスト22]中置演算子
> (+) ;;

 ▼

val it : (int -> int -> int) = <fun:it@2>

 これを利用して、下記のように関数を定義することも可能です。

[リスト23]既存の中置演算子を関数として定義
> let Add = (+) ;;

 ▼

val Add : (int -> int -> int)

 こんな風に独自の中置演算子を定義することもできます。

[リスト24]中置演算子の定義
> let ( @-@/ ) a b = a*b*3+125 ;;

 ▼

val ( @-@/ ) : int -> int -> int

 @-@/ は左右に置かれたパラメータ((aとb)に対して、a*b*3+125を実行する中置演算子です。実際に使用してみましょう。

[リスト25]定義した中置演算子を利用した式の実行
> 10 @-@/ 4 ;;

 ▼

val it : int = 245

 10*4*3+125の結果は、245なので、新たに定義した中置演算子が問題なく機能していることが分かります。

まとめ

 今回はF#における関数型言語特有の機能を紹介しました。関数型言語独特のシンプルなF#のプログラミング方法に徐々に慣れていただければ、と思います。次回は「F#のオブジェクト指向プログラミング」を中心に、解説予定です。

この記事は参考になりましたか?

連載通知を行うには会員登録(無料)が必要です。
既に会員の方はを行ってください。
C#プログラマのためのF#入門連載記事一覧

もっと読む

この記事の著者

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるLaravel実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

WINGSプロジェクト 星山 仁美(ホシヤマ ヒトミ)

WINGSプロジェクトについて>有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。 2026年時点での登録メンバは約50名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書記事多数。 RSS X: @WingsPro_info(公式)、@WingsPro_info/wings(メンバーリスト) Facebook

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

CodeZine(コードジン)
https://codezine.jp/article/detail/4430 2009/10/23 14:00

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー