本連載では、C#で「最低限」なんらかのコードを書いたことのあるプログラマーを対象に、関数型プログラミング言語「F#」について数回にわたり解説していきます。今回は言語指向プログラミングの第2弾として、外部DSLにて書かれた具体的表現を読み込んでF#に変換する技術を解説します。
はじめに
言語指向プログラミングの第2弾として、今回は外部DSLにて書かれた具体的表現を読み込んでF#に変換する技術について解説します。
アクティブパターン
アクティブパターンとはある値に複数の表現方法(フォーム)を与えることで、XMLなどの型付けされていない異種混在なデータに対しても、パターンマッチを可能にする技術です。
構文中のバナナクリップ(||)に囲まれた各部分をアクティブパターン識別子と呼びます。パターンマッチなどでアクティブパターンを使用する場合には、このアクティブパターン識別子経由で呼び出します。
アクティブパターン識別子は、アクティブパターンに引数として渡される入力データ用パーティションに対する名前のようなものです。
--------------------------------------------
//シングルケース
(|アクティブパターン識別子|) [引数] = 式
//マルチケース
(|アクティブパターン識別子1|アクティブパターン識別子2|..|) [引数] = 式
--------------------------------------------
//パターンマッチ基本使用方法
let パターンマッチ名 引数 =
match 引数 with
| パターン1(※1) -> 式
| パターン2 -> 式
--------------------------------------------
パターンマッチにおいて、パターンが識別子で2文字以上で大文字で始まる場合は(※1)、コンパイラがアクティブパターンなどのパターン識別子との照合を試みます。一致する識別子が見つからない場合は次のパターンが入力値(引数)と比較されます。
比較において一致が発見された場合、アクティブパターンの式部分に記述された該当する変換作業が行われ、その結果が戻され、それからパターンマッチが行われます。つまり、アクティブパターンの各アクティブパターン識別子を関数のように機能させ、その結果をパターンマッチングの一部として使用できます。これは言い方を変えれば、ある値をアクティブパターン(関数)で変換してからパターンマッチングを行う補助関数とも言えるでしょう。
アクティブパターンにはシングルケースとマルチケースの2種類があります。シングルケースとは、アクティブパターン識別子が1つしかないもので、引数として渡された入力データをあるたった1つの方法で変換します。一方、マルチケースとは、アクティブパターン識別子が複数あり、入力される値によって変換パターンが異なります。
いずれの場合にもパターンマッチからアクティブパターンを呼んで使用する際には、ちょうど関数を呼ぶようにアクティブパターンを呼び、アクティブパターンの式の部分に記述される変換作業を行います。
open System.Drawing
//シングルケースアクティブパターン
let (|TestRGB|) (n : System.Drawing.Color) = //※2
(n.R, n.G, n.B )
//パターンマッチ
let printRGB (n: System.Drawing.Color) =
match n with
|TestRGB(r, g, b) -> printfn " Red: %d Green: %d Blue: %d" r g b //※1
printRGB Color.Red;;
▼
Red: 255 Green: 0 Blue: 0 val ( |TestRGB| ) : Color -> byte * byte * byte val printRGB : Color -> unit
上記リストはシングルケースアクティブパターンの例です。パターンマッチのパターンとして定義されたTestRGBは、シングルケースアクティブパターンとして、唯一の式(変換作業)を実行し、System.Drawing.Color型の入力データを引数としてシングルケースアクティブパターン(※2)に渡し、処理をしてからパターンマッチ(※1)を行っています。
引数nを渡されたシングルケースアクティブパターンTestRGBは、いかなるSystem.Drawing.Color型の引数を受けた場合にも、その(n.R、n.G、n.B)の組を返します。
この記事は参考になりましたか?
- C#プログラマのためのF#入門連載記事一覧
-
- F#キーワードを再定義するコンピュテーション式
- F#のfslexとfsyaccを用いたコンパイラ作成
- F#によるアクティブケースを用いた外部DSLの変換
- この記事の著者
-
山田 祥寛(ヤマダ ヨシヒロ)
静岡県榛原町生まれ。一橋大学経済学部卒業後、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
※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です
この記事は参考になりましたか?
この記事をシェア
