Gaucheのutil.matchを勉強してみる
とりあえずはこんなかんじらしい
>> (match '(1 2 3) ((a b c) (list a b c))) => (1 2 3) >> (match '(1 (2 3)) ((a (b c)) (list a b c))) => (1 2 3)
つぎに、リスト処理させてみる
>>(match '(1 2 3 4) ((x . xs) (print x))) 1 =>#<undef> >>(match '(1 2 3 4) ((x . xs) (print xs))) (2 3 4)
なるほど。こりゃおもしろい。
>>((match-lambda ((x . xs) xs)) '(1 2 3 4)) =>(2 3 4)
おお、括弧がひとつ削れるのか。
>>((lambda (a) (match a ((x . xs) xs))) '(1 2 3 4)) =>(2 3 4)
こいつと同じと。確かに短くなってる(笑
で、変なのがあったのでそいつを実験
>>(match-lambda (() '())) =>#<closure #f> >>(lambda (x) (match x (() '()))) =>#<closure #f> >>((lambda (x) (match x (() '()))) ()) =>()
なるほどー。すごいなこりゃ。
並列で書いてあるのでそこを実験
>>((match-lambda (() "null") ((x . xs) xs)) ()) =>null >>((match-lambda (() "null") ((x . xs) xs)) '(1 2 3)) =>(2 3)
おお、null?時のifを一つ省略できる。
ってことで、match-lambdaを使ってクイックソートを書き直してみた
>>(define qsort (match-lambda (()()) ((x . xs) (receive (l r) (partition (lambda (y) (< y x)) xs) (append (qsort l) (list x) (qsort r)))))) =>qsort >>(qsort '(4 3 5 2 5 2 3 4)) =>(2 2 3 3 4 4 5 5)
よし。後はcutと準クオートだ。
ifがなくなるのは良い記法だなー
以下のように木構造をきれいに辿れるらしい。
(define (walk func tree) (match tree [() '()] [(x . xs) `(,(walk func x) . ,(walk func xs))] [x (func x)] )) -->walk (walk (lambda (x) (+ x 1)) '(1 2 (3 4 (5)) 6)) -->(2 3 (4 5 (6)) 7)