(define $Bool (type {[$var-match (lambda [$tgt] {tgt})] [$inductive-match (deconstructor {[true [] {[ {[]}] [_ {}]}] [false [] {[ {[]}] [_ {}]}] })] [$equal? (lambda [$val $tgt] (match [val tgt] [Suit Suit] {[[ ] ] [[ ] ] [[_ _] ]}))] })) (define $Something (type {[$var-match (lambda [$tgt] {tgt})] })) (define $Suit (type {[$var-match (lambda [$tgt] {tgt})] [$inductive-match (deconstructor {[spade [] {[ {[]}] [_ {}]}] [heart [] {[ {[]}] [_ {}]}] [club [] {[ {[]}] [_ {}]}] [diamond [] {[ {[]}] [_ {}]}] })] [$equal? (lambda [$val $tgt] (match [val tgt] [Suit Suit] {[[ ] ] [[ ] ] [[ ] ] [[ ] ] [[_ _] ]}))] })) (test ((type-ref Suit equal?) )) (define $Nat (type {[$var-match (lambda [$tgt] {tgt})] [$equal? (lambda [$val $tgt] (= val tgt))]})) (define $Mod (lambda [$m] (type {[$var-match (lambda [$tgt] {(mod tgt m)})] [$equal? (lambda [$val $tgt] (= (mod val m) (mod tgt m)))]}))) (test (match 10 Nat {[,(- 12 2) ] [_ ]})) (test (match 10 (Mod 13) {[,(- 12 2) ] [_ ]})) (define $Card (type {[$var-match (lambda [$tgt] {tgt})] [$inductive-match (deconstructor {[card [Suit (Mod 13)] {[ {[s n]}]}]})] [$equal? (lambda [$val $tgt] (match [val tgt] [Card Card] {[[ ] ] [[_ _] ]}))]})) (test (match 12> Card {[ ,12> ] [ ,10> ] [, 12> ] [ ] [_ ]})) (define $List (lambda [$a] (type {[$var-match (lambda [$tgt] {tgt})] [$inductive-match (deconstructor {[nil [] {[{} {[]}] [_ {}] }] [cons [a (List a)] {[{$x .$xs} {[x xs]}] [_ {}] }] [snoc [a (List a)] {[{.$xs $x} {[x xs]}] [_ {}] }] [join [(List a) (List a)] {[$tgt (let {[$loop (lambda [$ts] (match ts (List a) {[ {[{} {}]}] [ {[{} ts] @(map (lambda [$as $bs] [{x @as} bs]) (loop xs))}]}))]} (loop tgt))] }] [nioj [(List a) (List a)] {[$tgt (let {[$loop (lambda [$ts] (match ts (List a) {[ {[{} {}]}] [ {[{} ts] @(map (lambda [$as $bs] [{@as x} bs]) (loop xs))}]}))]} (loop tgt))] }] })] [$equal? (lambda [$val $tgt] (match [val tgt] [(List a) (List a)] {[[ ] ] [[ ] ] [[_ _] ]}))] }))) (test (match-map { } (List Something) [ [xs ys]])) (define $map (lambda [$fn $ls] (match ls (List Something) {[ {}] [ {(fn x) @(map fn xs)}]}))) (test (match-map { } (List Something) [> [hs x ts]])) (define $remove (lambda [$a] (lambda [$xs $x] (match xs (List a) {[ {}] [ rs] [ {y @((remove a) rs x)}]})))) (test ((remove Suit) { } )) (test ((remove Nat) {1 2} 1)) (define $remove-collection (lambda [$a] (lambda [$xs $ys] (match ys (List a) {[ xs] [ ((remove-collection a) ((remove a) xs y) rs)]})))) (test ((remove-collection Suit) { } { })) (define $subcollection (lambda [$xs] (match xs (List Something) {[ {{}}] [ (let {[$subs (subcollection rs)]} {@subs @(map (lambda [$sub] {x @sub}) subs)})] }))) (test (subcollection { })) (define $Multiset (lambda [$a] (type {[$var-match (lambda [$tgt] {tgt})] [$inductive-match (deconstructor {[nil [] {[{} {[]}] [_ {}] }] [cons [a (Multiset a)] {[$tgt (map (lambda [$t] [t ((remove a) tgt t)]) tgt)] }] [join [(Multiset a) (Multiset a)] {[$tgt (map (lambda [$ts] [ts ((remove-collection a) tgt ts)]) (subcollections tgt))] }] })] [$equal? (lambda [$val $tgt] (match [val tgt] [(Multiset a) (Multiset a)] {[[ ] ] [[ ] ] [[_ _] ]}))] }))) (define $one-pair (lambda [$ns] (match ns (Multiset Suit) {[> ] [_ ]}))) (test (one-pair { })) (define $list-nat (lambda [$ns] (match ns (List Nat) {[> n] [_ ]}))) (test (list-nat {1 1 3})) (define $multiset-nat (lambda [$ns] (match ns (Multiset Nat) {[> n] [_ ]}))) (test (multiset-nat {1 1 3})) (define $full-house (lambda [$ns] (match ns (Multiset Nat) {[ >>>>> ] [_ ] }))) (test (full-house {1 1 0 0 1})) (define $poker-hands (lambda [$Cs] (match Cs (Multiset Card) {[ ! >>>>> ] [ ! ! ! >>>>> ] [ ! ! ! >>>>> ] [ ! ! ! ! ! >>>>> ] [ ! >>>>> ] [ ! >>>>> ] [ ! ! >>>>> ] [ ! >>>>> ] [ >>>>> ]}))) (test (poker-hands { 4> 2> 5> 1> 3>})) (test (poker-hands { 1> 2> 1> 1> 2>})) (test (poker-hands { 4> 2> 5> 1> 3>})) (test (poker-hands { 4> 10> 5> 1> 3>})) (define $car (lambda [$as] (match as (List Something) {[ a]}))) (define $reverse (lambda [$as] (match as (List Something) {[ {}] [ {@(reverse rs) a}]}))) (define $min (lambda [$Ns] (match Ns (List Int) {[> n] [ (let {[$r (min Rs)]} (match (compare n r) Order {[ n] [_ r]}))]}))) (define $gcd (lambda [$Ns] (let {[$Ns2 (remove-all Ns 0)]} (match ns2 (Multiset Int) {[> n] [ (gcd {n @(map (lambda [$r] (mod r n)) Rs)})]})))) (define $gcd (lambda [$Ns] (let {[$Ns2 (remove-all Ns 0)]} (match Ns2 (Set Int) {[> n] [ (gcd {n @(map (lambda [$r] (mod r n)) Rs)})]}))))