;;;;; ;;;;; ;;;;; Collection ;;;;; ;;;;; ;;; ;;; List ;;; (define $list (lambda [$a] (matcher {[ [] {[{} {[]}] [_ {}]}] [ [a (list a)] {[{$x @$xs} {[x xs]}] [_ {}]}] [ [a (list a)] {[{@$xs $x} {[x xs]}] [_ {}]}] [ [(list a) (list a)] {[$tgt (match-all tgt (list a) [(loop $i [1 $n] $rs) [(foldr (lambda [%i %r] {xa_i @r}) {} (between 1 n)) rs]])]}] [ [(list a) (list a)] {[$tgt (match-all tgt (list a) [(loop $i [1 $n] $rs) [(foldr (lambda [%i %r] {@r xa_i}) {} (between 1 n)) rs]])]}] [,$val [] {[$tgt (if (eq? val tgt) {[]} {})]}] [$ [something] {[$tgt {tgt}]}] }))) (define $sorted-list (lambda [$a] (matcher {[ [] {[{} {[]}] [_ {}]}] [> [(sorted-list a) (sorted-list a)] {[$tgt (match-all tgt (list a) [(loop $i [1 $n] ) [(map (lambda [$i] (ref xa i)) (between 1 n)) rs]])]}] [ [(sorted-list a) (sorted-list a)] {[$tgt (match-all tgt (list a) [(loop $i [1 $n] $rs) [(map (lambda [$i] (ref xa i)) (between 1 n)) rs]])]}] [ [a (sorted-list a)] {[{$x @$xs} {[x xs]}] [_ {}]}] [,$val [] {[$tgt (if (eq? val tgt) {[]} {})]}] [$ [something] {[$tgt {tgt}]}] }))) ;; ;; Accessors ;; (define $nth (lambda [$n $xs] (match xs (list something) {[(loop $i [1 (- n 1)] ) x]}))) (define $take-and-drop (lambda [$n $xs] (match xs (list something) {[(loop $i [1 n] $rs) [(map (lambda [$i] a_i) (between 1 n)) rs]]}))) (define $take (lambda [$n $xs] (if (eq? n 0) {} (match xs (list something) {[ {x @(take (- n 1) xs)}] [ {}]})))) (define $drop (lambda [$n $xs] (if (eq? n 0) xs (match xs (list something) {[ (drop (- n 1) xs)] [ {}]})))) (define $take-while (lambda [$pred $xs] (match xs (list something) {[ {}] [ (if (pred x) {x @(take-while pred rs)} {})]}))) (define $take-while-by (lambda [$pred $xs] (match xs (list something) {[ {}] [ (if (pred x) {x @(take-while-by pred rs)} {x})]}))) (define $taile-until (lambda [$pred $xs] (match xs (list something) {[ {}] [ (if (not (pred x)) {x @(take-until pred rs)} {})]}))) (define $take-until-by (lambda [$pred $xs] (match xs (list something) {[ {}] [ (if (not (pred x)) {x @(take-until-by pred rs)} {x})]}))) (define $drop-while (lambda [$pred $xs] (match xs (list something) {[ {}] [ (if (pred x) (drop-while pred rs) xs)]}))) ;; ;; cons, car, cdr ;; (define $cons (lambda [$x $xs] {x @xs})) (define $car (lambda [$xs] (match xs (list something) {[ x]}))) (define $cdr (lambda [$xs] (match xs (list something) {[ ys]}))) (define $rac (lambda [$xs] (match xs (list something) {[ x]}))) (define $rdc (lambda [$xs] (match xs (list something) {[ ys]}))) ;; ;; list functions ;; (define $length (lambda [$xs] (foldl 2#(+ %1 1) 0 xs))) (define $map (lambda [$fn $xs] (match xs (list something) {[ {}] [ {(fn x) @(map fn rs)}]}))) (define $map2 (lambda [$fn $xs $ys] (match [xs ys] [(list something) (list something)] {[[ _] {}] [[_ ] {}] [[ ] {(fn x y) @(map2 fn xs2 ys2)}]}))) (define $map3 (lambda [$fn $xs $ys $zs] (match [xs ys zs] [(list something) (list something) (list something)] {[[ _ _] {}] [[_ _] {}] [[_ _ ] {}] [[ ] {(fn x y z) @(map3 fn xs2 ys2 zs2)}]}))) (define $map4 (lambda [$fn $xs $ys $zs $ws] (match [xs ys zs ws] [(list something) (list something) (list something) (list something)] {[[ _ _ _] {}] [[_ _ _] {}] [[_ _ _] {}] [[_ _ _ ] {}] [[ ] {(fn x y z w) @(map4 fn xs2 ys2 zs2 ws2)}]}))) (define $filter (lambda [$pred $xs] (foldr (lambda [%y %ys] (if (pred y) {y @ys} ys)) {} xs))) (define $partition (lambda [$pred $xs] [(filter pred xs) (filter 1#(not (pred %1)) xs)])) (define $zip (lambda [$xs $ys] (map2 (lambda [$x $y] [x y]) xs ys))) (define $zip3 (lambda [$xs $ys $zs] (map3 (lambda [$x $y $z] [x y z]) xs ys zs))) (define $zip4 (lambda [$xs $ys $zs $ws] (map4 (lambda [$x $y $z $w] [x y z w]) xs ys zs ws))) (define $lookup (lambda [$k $ls] (match ls (list [something something]) {[> x]}))) ; Note. `foldr` is used in the definition of the list matcher. (define $foldr (lambda [$fn %init %ls] (match ls (list something) {[ init] [ (fn x (foldr fn init xs))]}))) (define $foldl (lambda [$fn %init %ls] (match ls (list something) {[ init] [ (let {[$z (fn init x)]} (seq z (foldl fn z xs)))]}))) (define $reduce (lambda [$fn %ls] (foldl fn (car ls) (cdr ls)))) (define $scanl (lambda [$fn %init %ls] {init @(match ls (list something) {[ {}] [ (scanl fn (fn init x) xs)]})})) (define $iterate (lambda [$fn %x] (let* {[$nx1 (fn x)] [$nx2 (fn nx1)] [$nx3 (fn nx2)] [$nx4 (fn nx3)] [$nx5 (fn nx4)]} {x nx1 nx2 nx3 nx4 @(iterate fn nx5)}))) (define $repeated-squaring (lambda [$fn %x $n] (match n integer {[,1 x] [?even? (let {[$y (repeated-squaring fn x (quotient n 2))]} (fn y y))] [?odd? (let {[$y (repeated-squaring fn x (quotient n 2))]} (fn (fn y y) x))]}))) (define $append (lambda [$xs $ys] {@xs @ys})) (define $concat (lambda [$xss] (foldr (lambda [%xs %rs] {@xs @rs}) {} xss))) (define $reverse (lambda [$xs] (match xs (list something) {[ {}] [ {x @(reverse rs)}]}))) (define $intersperse (lambda [$in $ws] (match ws (list something) {[ {}] [ (foldl (lambda [$s1 $s2] {@s1 in s2}) {w} rs)]}))) (define $intercalate (compose intersperse concat)) (define $split (lambda [$in $ls] (match ls (list something) {[> {xs @(split in rs)}] [_ {ls}]}))) (define $split/m (lambda [$a $in $ls] (match ls (list a) {[> {xs @(split/m a in rs)}] [_ {ls}]}))) (define $find-cycle (lambda [$xs] (car (match-all xs (list something) [ $cs) >> [ys cs]])))) (define $repeat (lambda [%xs] {@xs @(repeat xs)})) (define $repeat1 (lambda [%x] {x @(repeat1 x)})) ;; ;; Others ;; (define $all (lambda [$pred $xs] (match xs (list something) {[ #t] [ (if (pred x) (all pred rs) #f)]}))) (define $any (lambda [$pred $xs] (match xs (list something) {[ #f] [ (if (pred x) #t (any pred rs))]}))) (define $from (lambda [$s] {s (+ s 1) (+ s 2) (+ s 3) (+ s 4) (+ s 5) (+ s 6) (+ s 7) (+ s 8) (+ s 9) (+ s 10) @(from (+ s 11))})) ; Note. `between` is used in the definition of the list matcher. (define $between (lambda [$s $e] (if (eq? s e) {s} (if (lt? s e) {s @(between (+ s 1) e)} {})))) (define $L./ (lambda [$xs $ys] (if (lt? (length xs) (length ys)) [{} xs] (match [ys xs] [(list math-expr) (list math-expr)] { [[ ] (let {[[$zs $rs] (L./ {@(map2 - (take (length yrs) xrs) (map (* $ (/ x y)) yrs)) @(drop (length yrs) xrs)} ys)]} [{(/ x y) @zs} rs])] })))) ;;; ;;; Multiset ;;; (define $multiset (lambda [$a] (matcher {[ [] {[{} {[]}] [_ {}]}] [ [a (multiset a)] {[$tgt (match-all tgt (list a) [> [x {@hs @ts}]])]}] [ [(multiset a)] {[$tgt (match [pxs tgt] [(list a) (multiset a)] {[[(loop $i [1 $n] ) (loop $i [1 n] $rs)] {rs}] [_ {}]})]}] [ [(multiset a) (multiset a)] {[$tgt (match-all tgt (list a) [(loop $i [1 $n] > $ts) [(map (lambda [$i] x_i) (between 1 n)) (concat {@(map (lambda [$i] rs_i) (between 1 n)) ts})]])]}] [,$val [] {[$tgt (match [val tgt] [(list a) (multiset a)] {[[ ] {[]}] [[ ] {[]}] [[_ _] {}]})]}] [$ [something] {[$tgt {tgt}]}] }))) ;; ;; multiset operation ;; (define $add (lambda [$x $xs] (if (member? x xs) xs {@xs x}))) (define $add/m (lambda [$a $x $xs] (if (member?/m a x xs) xs {@xs x}))) (define $delete-first (lambda [%x $xs] (match xs (list something) {[ {}] [ rs] [ {y @(delete-first x rs)}]}))) (define $delete-first/m (lambda [$a %x $xs] (match xs (list a) {[ {}] [ rs] [ {y @(delete-first/m a x rs)}]}))) (define $delete (lambda [$x $xs] (match xs (list something) {[ {}] [> {@hs @(delete x ts)}] [_ xs]}))) (define $delete/m (lambda [$a $x $xs] (match xs (list a) {[ {}] [> {@hs @(delete/m a x ts)}] [_ xs]}))) (define $difference (lambda [$xs $ys] (match ys (list something) {[ xs] [ (difference (delete-first y xs) rs)]}))) (define $difference/m (lambda [$a $xs $ys] (match ys (list a) {[ xs] [ (difference/m a (delete-first/m a y xs) rs)]}))) (define $include? (lambda [$xs $ys] (match ys (list something) {[ #t] [ (if (member? y xs) (include? (delete-first y xs) rs) #f)]}))) (define $include?/m (lambda [$a $xs $ys] (match ys (list a) {[ #t] [ (if (member?/m a y xs) (include?/m a (delete-first y xs) rs) #f)]}))) (define $union (lambda [$xs $ys] {@xs @(match-all [ys xs] [(multiset something) (multiset something)] [[ !] y]) })) (define $union/m (lambda [$a $xs $ys] {@xs @(match-all [ys xs] [(multiset a) (multiset a)] [[ !] y]) })) (define $intersect (lambda [$xs $ys] (match-all [xs ys] [(multiset something) (multiset something)] [[ ] x]))) (define $intersect/m (lambda [$a $xs $ys] (match-all [xs ys] [(multiset a) (multiset a)] [[ ] x]))) ;; ;; Simple predicate ;; (define $member? (lambda [$x $ys] (match ys (list something) {[> #t] [_ #f]}))) (define $member?/m (lambda [$a $x $ys] (match ys (list a) {[> #t] [_ #f]}))) ;; ;; Counting ;; (define $count (lambda [$x $xs] (foldl (match-lambda [something something] {[[$r ,x] (+ r 1)] [[$r $y] r]}) 0 xs))) (define $count/m (lambda [$a $x $xs] (foldl (match-lambda [a a] {[[$r ,x] (+ r 1)] [[$r $y] r]}) 0 xs))) (define $frequency (lambda [$xs] (let {[$us (unique xs)]} (map (lambda [$u] [u (count u xs)]) us)))) (define $frequency/m (lambda [$a $xs] (let {[$us (unique/m a xs)]} (map (lambda [$u] [u (count/m a u xs)]) us)))) ;; ;; Index ;; (define $elemIndices (lambda [$x $xs] (match-all xs (list something) [> (+ 1 (length hs))]))) ;;; ;;; Set ;;; (define $set (lambda [$a] (matcher {[ [] {[{} {[]}] [_ {}]}] [ [a (set a)] {[$tgt (match-all tgt (list a) [> [x tgt]])]}] [ [(set a)] {[$tgt (match [pxs tgt] [(list a) (set a)] {[[(loop $i [1 $n] ) (loop $i [1 n] _)] {tgt}] [_ {}]})]}] [ [(set a) (set a)] {[$tgt (match-all tgt (list a) [(loop $i [1 $n] > $ts) [(map (lambda [$i] x_i) (between 1 n)) tgt]])]}] [,$val [] {[$tgt (match [(unique val) (unique tgt)] [(list a) (multiset a)] {[[ ] {[]}] [[ ] {[]}] [[_ _] {}]})]}] [$ [something] {[$tgt {tgt}]}] }))) ;; ;; set operation ;; (define $fast-unique (lambda [$xs] (match-all (sort xs) (list something) [>> x]))) (define $unique (lambda [$xs] (reverse (match-all (reverse xs) (list something) [>>> x])))) (define $unique/m (lambda [$a $xs] (letrec {[$loop-fn (lambda [$xs $ys] (match [xs ys] [(list a) (multiset a)] {[[ _] ys] [[ ] (loop-fn rs ys)] [[ _] (loop-fn rs {@ys x})]}))]} (loop-fn xs {}))))