(define $Bool (type {[$var-match (lambda [$tgt] {tgt})] [$inductive-match (deconstructor {[true [] {[ {[]}] [_ {}]}] [false [] {[ {[]}] [_ {}]}] })] [$equal? (lambda [$val $tgt] (match [val tgt] [Suit Suit] {[[ ] ] [[ ] ] [[_ _] ]}))] })) (define $Order (type {[$var-match (lambda [$tgt] {tgt})] [$inductive-match (deconstructor {[less [] {[ {[]}] [_ {}]}] [equal [] {[ {[]}] [_ {}]}] [greater [] {[ {[]}] [_ {}]}] })] [$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] {[[ ] ] [[ ] ] [[ ] ] [[ ] ] [[_ _] ]}))] })) (define $Nat (type {[$var-match (lambda [$tgt] {tgt})] [$equal? (lambda [$val $tgt] (= val tgt))]})) (define $Int (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)))]}))) (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] {[[ ] ] [[_ _] ]}))]})) (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)] {[[ ] ] [[ ] ] [[_ _] ]}))] }))) (define $map (lambda [$fn $ls] (match ls (List Something) {[ {}] [ {(fn x) @(map fn xs)}]}))) (define $remove (lambda [$a] (lambda [$xs $x] (match xs (List a) {[ {}] [ rs] [ {y @((remove a) rs x)}]})))) (define $remove-all (lambda [$a] (lambda [$xs $x] (match xs (List a) {[ {}] [ ((remove-all a) rs x)] [ {y @((remove-all a) rs x)}]})))) (define $remove-collection (lambda [$a] (lambda [$xs $ys] (match ys (List a) {[ xs] [ ((remove-collection a) ((remove a) xs y) rs)]})))) (define $subcollections (lambda [$xs] (match xs (List Something) {[ {{}}] [ (let {[$subs (subcollections rs)]} {@subs @(map (lambda [$sub] {x @sub}) subs)})] }))) (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 $poker-hands (lambda [$Cs] (match Cs (Multiset Card) {[ ! >>>>> ] [ ! ! ! >>>>> ] [ ! ! ! >>>>> ] [ ! ! ! ! ! >>>>> ] [ ! >>>>> ] [ ! >>>>> ] [ ! ! >>>>> ] [ ! >>>>> ] [ >>>>> ]}))) (define $min (lambda [$Ns] (match Ns (List Int) {[> n] [ (let {[$r (min Rs)]} (match ((type-ref Int compare) n r) Order {[ n] [_ r]}))]}))) (define $gcd (lambda [$ns] (let {[$ns2 ((remove-all Int) ns 0)]} (match ns2 (Set 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)})]})))) (define $car (lambda [$xs] (match xs (List Something) {[ x]}))) (define $reverse (lambda [$xs] (match xs (List Something) {[ {}] [ {@(reverse rs) x}]}))) (define $member? (lambda [$a] (lambda [$x $ys] (match ys (List a) {[ ] [ ] [ ((member? a) x ys)] })))) (define $unique (lambda [$a] (lambda [$xs] (let {[$loop (lambda [$xs $ys] (match xs (List a) {[ ys] [ (match ((member? a) x ys) Bool {[ (loop rs ys)] [ (loop rs {@ys x})] [_ {}] })]}))]} (loop xs {}))))) (define $Set (lambda [$a] (let {[$Loop (type {[$var-match (lambda [$ts1 $ts2] (map (lambda [$sts2] {@ts1 @sts2}) (subcollections ts2)))] [$inductive-match (deconstructor {[nil [] {[[{} _] {[]}] [[_ _] {}] }] [cons [a Loop] {[[$ts1 $ts2] (map (lambda [$t] [t [((remove a) ts1 t) {@ts2 t}]]) {@ts1 @ts2})] }] [join [(Set a) Loop] {[[$ts1 $ts2] (map (lambda [$ts] [ts [((remove-collection a) ts1 ts) {@ts2 ts}]]) (subcollections {@ts1 @ts2}))] }] })] [$equal? ] })]} (type {[$var-match (lambda [$tgt] {$tgt})] [$inductive-match (lambda [$tgt] (let {[$tgt2 ((unique a) tgt)]} ((type-ref Loop inductive-match) [tgt2 {}])))] [$equal? ]})))) (test (match-map { } (List Something) [ [xs ys]])) (test (match-map { } (List Something) [> [hs x ts]])) (test (match-map { } (Multiset Something) [ [hs x ts]])) (test (match-map { } (Set Something) [ [hs ts]])) (test ((remove-collection Suit) { } { })) (test (subcollections { })) (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>}))