Egisonのパターンマッチ式
この記事は,2019年Egisonアドベントカレンダーの3日目の記事です.
パターンマッチを記述するためのいくつかの構文をEgisonは提供しています. そのうちもっとも基本的な構文はmatchAll式です.
matchAll式は,ターゲット(上記の場合, [1,2,3]
),マッチャー(上記の場合, list something
),マッチ節(上記の場合, $x :: $xs -> (x,xs)
)から構成されます.
マッチ節は,パターン(上記の場合, $x :: $xs
)とボディ(上記の場合, (x,xs)
)からなります.
matchAll式は,既存のプログラミング言語のマッチ式と同様に,ターゲットとパターンのパターンマッチを試みて,もしマッチしたらそのマッチ節のボディを評価します.
EgisonのmatchAll式の特徴は, (1) matchAllという名前と結果としてリストを返すことと, (2) マッチャーという追加の引数をとることにあります.
(1) の特徴は,複数の結果をもつパターンマッチをサポートするための特徴です.
matchAll式は複数のパターンマッチの結果すべてについてボディを評価して,その結果を集めてリストとして返します.
上記の例のパターンに使われている ::
はコンスパターンと呼ばれるリストを先頭の要素と残りのリストに分解するパターンコンストラクタです.
そのため,上記の例の場合は,パターンマッチの結果が一つであるので,長さが 1 のリストを返しています.
(2) の特徴は,パターンマッチアルゴリズムの拡張性とパターンの多相性を実現するための特徴です.
マッチャーはEgison以外の言語ではみられない独自のオブジェクトで,パターンマッチアルゴリズムを保持するためのオブジェクトです.
matchAll式に渡すマッチャーを変えると他のmatchAllの引数がすべて同じでも結果が変わります.
例えば,上記のmatchAll式のマッチャーを multiset something
に変えるとターゲットのリストを多重集合としてパターンマッチし,複数の分解結果を得られます.
マッチャーを変えるとこのmatchAll式の評価結果が変わる理由は, マッチャーを multiset something
に変えた影響で ::
パターンコンストラクタの解釈の方法が変わるからです.
上述したように,リストのマッチャーが使われているとき, ::
はリストを先頭の要素と残りのリストに分解します.
対して,多重集合のマッチャーが使われているとき, ::
はリストをある要素とその要素をのぞいた残りのリストに分解します.
その結果,要素数が 3 のリストがターゲットの場合, 3 つの分解結果が返ってきます.
Egisonは非線形パターンをサポートしています. 非線形パターンとは,パターン内で変数に束縛した値を同じパターン内で参照するようなパターンのことをいいます. matchAll式がサポートする複数の結果を持つパターンマッチと,非線形パターンを組み合わせると,パターンマッチで簡潔に記述できるアルゴリズムの範囲が大きく広がります. たとえば,前回の記事「プログラミング言語 Egison とは?」で紹介した intersect や unique は matchAll式と非線形パターンを組み合わせて記述されていました. 次回以降の記事で,Egisonのパターンマッチを活かしたプログラミングの方法についてもっと踏み込んでいきます.
もうひとつのEgisonの重要な特徴に list や multiset は組み込みではなく,ユーザーが定義できることがあります. Egisonパターンマッチを活かしたプログラミングテクニックを紹介したあとの記事では,マッチャー定義の方法も紹介します.
ご期待ください.