0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Luaでパターンマッチング

Posted at

Lua ではテーブル同士の比較は同一比較(アドレス比較)になり、内容で比較することはできない。
tamale.lua を使うと、
『内容、構造を調べ、当てはまるなら、続く文(ブロック)を実行する』
ができる

[注意]このライブラリはもうずっとメンテナンスされていないため、lua5.2 から非対応の古いライブラリだが、
module 宣言を消し、return するテーブルを作ってそれに関数をはやしてゆけばlua5.4でも使うことができる

サンプルコード

2048でタイルを左に詰めるコード(yuescript)
(lume.sliceはstring.subの配列版)
(...はテーブルを展開する)

.moon
moveLeft = (ss)->
	recur, a = nil, tamale.var'a' -- matcher自体を再帰関数にするためには前方宣言が必要。
	recur = tamale.matcher{
		{[], []}
		{[0,], partial: true, (c)-> [...recur(lume.slice(c.input, 2)), 0]}
		{[a, a], partial: true, (c)-> [c.a*2, ...recur(lume.slice(c.input, 3)), 0]}
		{[a, 0, a], partial: true, (c)-> [c.a*2, ...recur(lume.slice(c.input, 4)), 0, 0]}
		{[a, 0, 0, a], (c)-> [c.a*2, 0, 0, 0]}
		{[a,], partial: true, (c)-> [c.a, ...recur(lume.slice(c.input, 2))]} -- lume.concatで{}を扱うとそのままつける?バグがある?
	}
	[recur(s) for s in *ss]

ルール集の記述

  • matcher にルール集(配列)を渡すと関数を返す
    上から(先頭から)順に調べる
  • else 節の表記法はない([], partial: trueで代用)(->trueでも)。else が何もしないなら省略できる
  • ルールからmatcherを再帰呼出しをするには前方宣言が必要

その中の一つのルールの記述

  • 一つのルールは{[1] = パターン, [2] = 実行する関数, partial = true}のように配列に付加情報を同居させる形
  • 数値などのほかtamale.var'x'で変数を定義、キャプチャできる
  • when = condition でガード節を付けられる
  • partial = trueで一部のキーだけを調べてパターンに当てはまるか判断するようになる
    luaでは配列を記述することは{[1] = .. , [2] = ..}というキーがあることと同じなので、パターンに配列を書くことは『先頭から(パターンに記述した配列の長さ分)調べる』という意味になる
  • 実行する関数はキャプチャしたものを引数として受け取る
    • local a = tamale.var'a'とすると、パターン中で使え、capture.aで受け取れる
    • capture.inputでmatch関数に渡されたテーブルを受け取れる

その他のパターンの書き方

  • tamale.P で正規表現での比較がある
  • 関数: マッチ関数に渡された値(input)を引数に呼ばれ真であれば成立

その他の付加情報

  • ids に値のリストを渡すと、同一比較(アドレス比較)になる
  • index で優先的に比較するよう関数を定めることができる(高速化)?
  • debug は stderr に色々出力するだけで動作は変わらない?

実行する関数の代わりに戻り値を書ける

  • (関数の場合は多値が返せるが)返せる値は1つ、2番めには情報が返る

注意点

  • N+1 のような便利な記述はない
  • 網羅性チェックもない
  • 無限を表すテーブルを渡すとスタックオーバーフローする(たとえ最初の1つ2つしか調べなくても)

その他

他にもメンテナンスされていないライブラリがある

  • luacombine(組み合わせ)
    少しの修正で動く
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?