suit := algebraicDataMatcher | spade | heart | club | diamond card := algebraicDataMatcher | card suit (mod 13) poker cs := match cs as multiset card with | card $s $n :: card #s #(n-1) :: card #s #(n-2) :: card #s #(n-3) :: card #s #(n-4) :: _ -> "Straight flush" | card _ $n :: card _ #n :: card _ #n :: card _ #n :: _ :: [] -> "Four of a kind" | card _ $m :: card _ #m :: card _ #m :: card _ $n :: card _ #n :: [] -> "Full house" | card $s _ :: card #s _ :: card #s _ :: card #s _ :: card #s _ :: [] -> "Flush" | card _ $n :: card _ #(n-1) :: card _ #(n-2) :: card _ #(n-3) :: card _ #(n-4) :: [] -> "Straight" | card _ $n :: card _ #n :: card _ #n :: _ :: _ :: [] -> "Three of a kind" | card _ $m :: card _ #m :: card _ $n :: card _ #n :: _ :: [] -> "Two pair" | card _ $n :: card _ #n :: _ :: _ :: _ :: [] -> "One pair" | _ :: _ :: _ :: _ :: _ :: [] -> "Nothing" assertEqual "poker" (poker [Card Spade 5, Card Spade 6, Card Spade 7, Card Spade 8, Card Spade 9]) "Straight flush" assertEqual "poker" (poker [Card Spade 5, Card Diamond 5, Card Spade 7, Card Club 5, Card Heart 5]) "Four of a kind" assertEqual "poker" (poker [Card Spade 5, Card Diamond 5, Card Spade 7, Card Club 5, Card Heart 7]) "Full house" assertEqual "poker" (poker [Card Spade 5, Card Spade 6, Card Spade 7, Card Spade 13, Card Spade 9]) "Flush" assertEqual "poker" (poker [Card Spade 5, Card Club 6, Card Spade 7, Card Spade 8, Card Spade 9]) "Straight" assertEqual "poker" (poker [Card Spade 5, Card Diamond 5, Card Spade 7, Card Club 5, Card Heart 8]) "Three of a kind" assertEqual "poker" (poker [Card Spade 5, Card Diamond 10, Card Spade 7, Card Club 5, Card Heart 10]) "Two pair" assertEqual "poker" (poker [Card Spade 5, Card Diamond 10, Card Spade 7, Card Club 5, Card Heart 8]) "One pair" assertEqual "poker" (poker [Card Spade 5, Card Spade 6, Card Spade 7, Card Spade 8, Card Diamond 11]) "Nothing"