++C++; // 未確認飛行 C ブログ

http://ufcpp.net/

C# 7に向けて(6): Pattern matching

with one comment

先日の続き、C# 7の目玉になるであろう機能、pattern matching と record types

の片割れ、pattern matching の話。

昨日の record types (もう、自分が書くクラスの7割くらいは record types で書くことになりそうな勢い)と比べると出番は少ないでしょうが、なかなかに便利そうな機能です。

マッチング構文

以下のような感じで、オブジェクトの型や値のマッチングを、再帰的に行う構文が追加されます。

  • 定数マッチング
    • x is 1
    • 定数との比較
    • 下記の
  • 型マッチング
    • x is T t
    • x が特定の型 T の時にマッチ
    • その時、x を T にキャストしたものが t に入る
  • プロパティ マッチング
    • x is T { X is int , Y is Int }
    • x の型についてマッチした後、そのプロパティに大してもマッチング
  • 再帰マッチング
    • x is T(var a, 1)
    • is 演算子というものに展開される
      • record types の場合はこの is 演算子もコンパイラーが生成
      • ユーザー定義の is 演算子も書ける
    • var を書いたところは、何とでもマッチした上で、その場所に入っている値を変数 a に代入する
    • var x = new T(1, 2) みたいなので構成(composition)するのの逆で、x is T(var a, var b) みたいなので分解(decomposition)できる
  • 何とでもマッチング(ワイルドカード)
    • x is T(var a, *)
    • 何でもいいし、var 不要(値をとりだす必要がない)場合には、そこに * を書く

最後の再帰マッチングについては、composition と decomposition がきっちり対応する書き方になるのが結構きれい。

is 演算子を書く以外に、switch ステートメントでもパターン マッチングできるように拡張したいようです。

パラダイムが変わるのか

僕がこういう感じのセクション タイトルを付けるときは、だいたい「えっ… 別に」という答え付きだったりするわけですが。

こういう機能が出てくると、ついつい「オブジェクト指向 VS 関数型」、「関数型の方がいい!」「オブジェクト指向から関数型へのパラダイムシフト!」的な流れになりがちですが、まあ、どっちも使うでしょう、普通に。

自分の最近書いたコードで言うと、ビュー側での表示の切り替えのコード。例えば、要所を抜き出しすと、以下のような

RPG ゲーム的なものを想像してもらって、コマンド選択で「たたかう」だの「まほう」だののコマンド選択式で何らかのアクションを起こすようなものの一部分を抜き出したものです(実際、これを大規模化した感じのコードを前に書きまして)。

いわゆるモデル側では、やっぱり、仮想メソッドを使って処理の切り替えをやる方がシンプルでいい実装だと思うんですよね。この例で言うと、Model.cs 内、ApplyTo を呼んでいる部分。

一方で、これをやるためには、オブジェクト自身がやりたい処理を全部把握している必要があります。ApplyTo (選択したアクションを、ターゲットに適用)の場合は、モデル自身がやるべきことを知っているので仮想メソッドにできる。ビュー側はそうはいきません。ビューのことはビューしか知らず、モデル側(BattleAction)内部のメソッドとしては処理を書けません。

で、結局、往々にしてビュー側コードはどうなるかというと… 型を見ての分岐。

as してから != null チェックだらけに(AsPatternMatching.cs みたいな)。

これに対して、C# 7で導入予定の pattern matching を使えば、型による分岐が楽になります(Cs7PatternMatching.cs)。

争点

結構大きな機能追加なので、まだまだこれから仕様を固めないと行けないところとか、もめそうなところとか結構多め。

  • 匿名型どうしよう?
    • record types と匿名型でアプローチが違いすぎるんだけども
  • 配列、List、Dictionary のマッチング
  • switch でいいの?
    • switch っていう単語は今まで通りな legacy な switch であってほしい。マッチングには match キーワード導入しない?
    • switch みたいなステートメントじゃなくて、式にしてほしい
  • パターン マッチング式中での dynamic 型の扱い
  • switch での完備性のチェック
    • その3で説明した「completeness」
    • パターン マッチングがあり得るパターンを漏れなく網羅しているかどうかをチェックしたいけども、できる?
  • 再帰マッチングとプロパティ マッチングは混在させたい?
  • ワイルドカードは * なの?
    • F# とかでは _ だけども…
    • _ の方がなじみはあるものの、C# では _ は普通に識別子に使える名前だし…

Written by ufcpp

2015年2月7日 @ 02:56

カテゴリー: C#

Tagged with

コメント / トラックバック1件

Subscribe to comments with RSS.

  1. […] C# 7に向けて(6): Pattern matching […]


コメントを残す

以下に詳細を記入するか、アイコンをクリックしてログインしてください。

WordPress.com ロゴ

WordPress.com アカウントを使ってコメントしています。 ログアウト / 変更 )

Twitter 画像

Twitter アカウントを使ってコメントしています。 ログアウト / 変更 )

Facebook の写真

Facebook アカウントを使ってコメントしています。 ログアウト / 変更 )

Google+ フォト

Google+ アカウントを使ってコメントしています。 ログアウト / 変更 )

%s と連携中

%d人のブロガーが「いいね」をつけました。