次にマルチケースアクティブパターンの例を挙げてみます。
//マルチケースアクティブパターン
let (|Even|Odd|) n = //※1
if n % 2 = 0 then Even
else Odd
//パターンマッチ
let testNum x =
match x with //※2
| Even -> printfn "given value %d is Even" x
| Odd -> printfn "given value %d is Odd" x;; //※3
testNum 3 //※4
testNum 4;;
▼
val ( |Even|Odd| ) : int -> Choice<unit,unit> val testNum : int -> unit > given value 3 is Odd given value 4 is Even
上記のリストの(※1)は引数nが偶数のときEven、奇数のときOddにnを分類するアクティブパターンです。※2のパターンマッチングで使用され、引数nをアクティブパターンに渡して処理をしてからパターンマッチングを行いします。testNum 3(※4)が実行されると、まず引数n(3)がアクティブパターンに引数として渡されます。n%2=1となり、アクティブパターンはnをOddに分類します。そのため、※2のパターンマッチでは、Oddのパターン(※3)が選択され処理されます。
上記の例は、引数として入力されるデータが全ていずれかのアクティブパターン識別子に分類されることを前提としていますが、実際にはそうではありません。ある種のデータのみに該当処理をして各アクティブパターン識別子に分類したいが、”それ以外”として分類したいデータがある(つまりマッチングが失敗する可能性がある)というアクティブパターンを設定することが可能で、そのようなアクティブパターンをパーシャルアクティブパターンと呼びます。
-------------------------------------------- let (|アクティブパターン識別子|_|) [ 引数 ] = 式 --------------------------------------------
アクティブパターン識別子の最後に|_|を追記し、式にも該当パターンがなかった場合の処理を追記します。パーシャルアクティブパターンはオプション型の値を返します。つまり、戻り値はSome(値)もしくは、Noneになります。
//パーシャルアクティブパターン
let (|Multiple3|_|) n = //※1
if n % 3 = 0 then Some(n)
else None
let (|Even|_|) n =
if n % 2 = 0 then Some(n)
else None
//パターンマッチ
let testNum1 x = //※2
match x with
| Multiple3 y & Even z -> printfn "%d is divisible by 3 and 2." x
| _ -> printfn "%d is not divisible by 2 or %d is not divisible by 3" x x
testNum1 3
testNum1 4
testNum1 6;;
▼
3 is not divisible by 2 or 3 is not divisible by 3 4 is not divisible by 2 or 4 is not divisible by 3 6 is divisible by 3 and 2. val ( |Multiple3|_| ) : int -> int option val ( |Even|_| ) : int -> int option val testNum1 : int -> unit
上記のリストでは、まずパターンマッチ(※2)で最初に出てくるMultiple3のアクティブパターンが引数を渡した時、ヒットするかどうかを確認します。アクティブパターンは引数が3の倍数の時、値はマッチを見つけMultiple3に分類され、値を返します。それ以外のとき、つまり指定された他のパターンがヒットしない場合、検索に失敗した場合にはNoneを返します。
その次に、パターンマッチは、アクティブパターンEvenに引数を渡したときヒットするかどうかを確認します。アクティブパターンは値が2の倍数のときはEvenに分類され値を返し、それ以外の場合はNoneを返します。2つのアクティブパターンがともにtrueの場合には値がdivisible by 3 and 2と表示されます。
この記事は参考になりましたか?
- 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
※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です
この記事は参考になりましたか?
この記事をシェア
