パターンマッチを使う関数を3つほど。
データコンストラクタを外す関数。
(define $mcer (algebraic-data-matcher {<a integer> <b integer>})) (define $cut (lambda $xs (match xs mcer {[<a $x> x] [<b $x> x]}))) > (cut <A 6>) 6 > (cut <B 7>) 7 > (cut <C 7>) Error: failed pattern match >
1個以上の連続したデータにマッチする関数。
(define $any-series (lambda [$x $xs] (if (eq? x (car xs)) (match xs (list something) {[(loop $i [1 $n] <cons ,x ...> (| <cons ^,x _> <nil>)) (take n (repeat1 x)) ] }) (if (empty? (cdr xs)) {} (any-series x (cdr xs)))))) > (any-series 3 {1 2 3 3 3 4}) {3 3 3} > (any-series 5 {1 2 3 3 3 4}) {} >
Haskellでいうgroupみたいなもの。
(define $group (lambda $xs (delete {} (match-all (append {{}} xs) (list something) [<join <snoc $x0 _> (loop $i [1 $n] <cons (& $x_i (& ^,x0 ,x_1)) ...> (| <cons ^,x_1 _> <nil>)) > (take n (repeat1 x_1)) ] )))) > (group {1 1 2 2 2 3 3}) {{1 1} {3 3} {2 2 2}} > (group {1 1 2 2 2 3 3 4 5 5 5 5 5 5 5}) {{4} {1 1} {3 3} {2 2 2} {5 5 5 5 5 5 5}} >
順番が変わってしまうのはご愛嬌。