yamasushi(2013/04/20 08:31:25 UTC)パターンマッチングについての情報をまとめてみます。
I hope this article serves well as an introduction to match. It is one of my favorite Scheme forms and it is very popular in general, too: According to the current Salmonella reverse dependency ranking, the matchable egg is the most depended on egg in all of Chicken!
equal?で比較するcase
caseシンタックスは、キーと一致するclauseを判定するのにeqv?を使いますが、eqv?ではなくequal?が必要なときはどうしたらいいでしょうか? もちろんcondを使って、自分でcondのtest clauseにequal?を並べることはできますが、(1)キーの生成に副作用がある場合にはプログラマが明示的にローカル変数を作らないといけない、(2)副作用がないとしても同じキーを並べるのが面倒、という理由で、equal?で比較するcaseがあると便利だと思うのですが。自分でシンタックスを追加してもいいとはいえ、そういうものが標準で用意されていないのは、なにかいいやり方が別にあるから?
Shiro(2005/09/24 02:02:16 PDT): いえ、たぶん必要ならマクロですぐ書けるけれど 標準にするほどには頻繁に必要とされない(もしくは一般化しにくい)、 という理由なんではないかと推測します。 ちなみにutil.matchを使えば似たようなことが出来ます。Scheme的には 「どうせやるならこのくらいまで一般化したい」という心理が働くのかも。
(match var ((or "abc" "def" "ghi") ....) ;;; 文字列のいずれかにマッチ ((or '(abc) '(def) '(ghi)) ...) ;;; リテラルリストにマッチ )
(use srfi-13) (use util.match) (define main (match-lambda ((program filename) (with-input-from-file filename (cut port-for-each (lambda (line) (print (string-trim-right (or (string-scan line #\; 'before) line)))) read-line)) 0) ((program . _) (print "Usage: " program " <filename>") 1)))
コマンドライン引数の扱いは、オプションをlet-argsでパーズした後、残りの引数に matchをかける、っていうのをよくやる。
(use gauche.parseopt) (use util.match) (define (main args) (let-args (cdr args) ([#f "h|help" => (cut usage 0)] . args) (match args [(file) ...処理...] [_ (usage 1)])))
Tag: util.match