Egison advocates a pattern-match oriented style of programming and offers poker hands as an example:
def suit := algebraicDataMatcher
| spade
| heart
| club
| diamond
def card := algebraicDataMatcher
| card suit (mod 13)
def poker cs :=
match cs as multiset card with
| [card $n, card #n, card #n, card #n, ]
-> "Four of a kind"
| [card $m, card #m, card #m, card $n, card #n]
-> "Full house"
...
| [, , , , _] -> "Nothing"
Note match ... as multiset ...
which allows us to match without regard to
the order of the input data. The syntax to bind variables ($n
) in patterns and thence
refer to them (#n
) is elegant.
The Curry tutorial gives the poker hand problem as an example as well:
{-# OPTIONS_CYMAKE -F --pgmF=currypp --optF=defaultrules #-}
data Suit = Club | Spade | Heart | Diamond
data Rank = Ace | King | Queen | Jack | Ten | Nine | Eight
| Seven | Six | Five | Four | Three | Two
deriving (Eq)
data Card = Card Rank Suit
rank (Card r _) = r
hand (x++[]++z) | map rank (x++z) == [r,r,r,r] = Just "Four of a kind" where r free
hand (x++[a]++y++[b]++z) | map rank (x++y++z) == [r,r,r] && rank a == rank b = Just "Full house" where r free
...
hand'default = Nothing
This uses functional logic programming (note the where ... free
clause); lists
are ordered and Curry gives us no relief from this, but it is clearer than
solutions in functional programming. Logic programming allows us to recover some
of Egison's pattern-matching functionality in a more principled manner.