TODAY'S HEADLINES  |   ARTICLE ARCHIVE  |   FORUMS  |   TIP BANK
 Specialized Dev Zones Research Center eBook Library .NET Java C++ Web Dev Architecture Database Security Open Source Enterprise Mobile Special Reports 10-Minute Solutions DevXtra Blogs Slideshow

# Beginning F#: Card Tricks : Page 4

## Discover the power of F# by writing a complete card-shuffling program in only 92 lines of code.

 by Seth Livingston
 Jan 13, 2009
 Page 4 of 4
Pattern Matching and Functional Polymorphism
One of F#'s notable features is its ability to make inferences about expressions. Here's an F# Interactive exploration showing how F# makes inferences about types:

``````   > let list1 = [ 1; 2; 3];;
val list1 : int list

> let list2 = [ [ "apple"; "orange" ]; [ "pear"; "mango" ] ];;
val list2 : string list list

> let add x y =
x + y
;;

val add : int -> int -> int

val it : int = 5

----^^^^^^

stdin(8,5): error FS0001: This expression has type
string
but is here used with type
int.
``````
F# Interactive's response to the first line of code above is to examine the list1 expression and determine that it is of type int list: a list of integers. F# similarly infers that the list2 expression is of type string list list: a list of lists of strings.

In the third entry, F# examines the add function, and by looking at the use of the x and y arguments, infers that it is of type int -> int -> int: a function that accepts two integers and evaluates to an integer.

You can use F#'s inference capabilities to look for specific patterns in types and expressions and then take action accordingly. This process is called pattern matching, and you've already see it in action throughout this article. First, you used it to extract the elements of a 3-tuple:

``````   > let tupleOfThree = ("Abraham", "Lincoln", 16);;
val tupleOfThree : string * string * int

> let x, y, z = tupleOfThree;;
val z : int
val y : string
val x : string

> x;;
val it : string = "Abraham"

> y;;
val it : string = "Lincoln"

> z;;
val it : int = 16
``````
You also used it to extract only the relevant elements of 2-tuple in a comparison function:

``````      let sortedWeightedCards =
List.sort
(fun (_, leftWeight) (_, rightWeight) -> leftWeight-rightWeight)
weightedCards
``````
The match keyword is another way to take advantage of pattern matching:

``````   > let findTwosInTuple tuple =
match tuple with
| (2, _) -> "2 is the first member of the tuple!"
| (_, 2) -> "2 is the second member of the tuple!"
| _ -> "There isn't a 2 in this tuple";;

val findTwosInTuple : int * int -> string

> findTwosInTuple (2, 0);;
val it : string = "2 is the first member of the tuple!"

> findTwosInTuple (3, 0);;
val it : string = "There isn't a 2 in this tuple"

> findTwosInTuple(99, 2);;
val it : string = "2 is the second member of the tuple!"
``````
Pattern matching is useful in far more ways than this article can list, but the most prominent use for the construct in F# is functional polymorphism: allowing a function to change its behavior based on the type (or pattern) of the expression it's acting on. The playing card application provides a perfect example.

After the playing card application draws cards from the deck, you need to display the results in the console window. Here's a function called printCard that accepts a playing card, but that behaves differently based on the card type (face card, rank card, or joker). The match construct makes this trivial:

``````       let printCard card =
match card with
| RankCard(rank, suit) -> printfn "%A of %A" rank suit
| FaceCard(Ace, suit) -> printfn "Bam! An Ace of %A" suit
| FaceCard(face, suit) -> printfn "Nice! %A of %A" face suit
| Joker -> printfn "Joker is wild!"
``````
The printCard function is polymorphic with regard to rank cards, aces, face cards and jokers. The polymorphic behavior in this case is a trivial printfn expression, but you could easily replace that with function expressions that encapsulate complex behaviors.

The application's main function is now complete:

``````   let main =
let shuffledCards = shuffle fiftyFourCards
let (drawnCards, remainingDeck) = draw 10 shuffledCards
let printCard card =
match card with
| RankCard(rank, suit) -> printfn "%A of %A" rank suit
| FaceCard(Ace, suit) -> printfn "Bam! An Ace of %A" suit
| FaceCard(face, suit) -> printfn "Nice! %A of %A" face suit
| Joker -> printfn "Joker is wild!"
List.iter printCard drawnCards
``````
Here's the console output from one execution:

``````   Bam! An Ace of Clubs
Joker is wild!
Eight of Diamonds
Nine of Clubs
Five of Clubs
Nice! King of Diamonds
Three of Clubs
``````
As you can see by the terseness of the code you've written, F# is an elegant, logical language. You've explored the functional programming approach and some of F#'s native features, such as:

• Discriminated unions
• Tuples
• Lists and list sequence expressions
• Functions and recursion
• Pattern matching and functional polymorphism
You've created a simple yet powerful playing card application using only 92 lines of code. Stay tuned for a follow-up article that explores some of F#'s more advanced features to implement the core of any playing card game: the rules.

Seth Livingston is the CTO of Adventos, LLC, a training, mentoring, and delivery partner for Microsoft solutions and software development best practices. Seth splits his time among seminars, classes, mentoring, and guiding Adventos' technical direction. He lives in McKinney, Texas.