I'm learning F# by doing various small projects. One of them is a problem where the program reads Poker hands and rates them. It's Texas Hold'Em, so for each player it tries every five card selection from seven cards.
When it's time for scoring I have made a set of functions that each evaluate a hand and produces an Score option of whether that hand matches or not:
type Score =
{ Points: int
Desc: string }
val tryStraightFlush: PokerHand -> Score option
val tryFourOfAKind: PokerHand -> Score option
// more functions ..
val getHighCard: PokerHand -> Score option
type PokerHand =
class
new : cards:Card list -> PokerHand
member Cards : Card list
member HighCard : Card option
end
But now I have a problem, because I need to use the options that these functions produce, so I cannot do a match like this:
//Non-working code.
//Something roughly similar to this would be nice.
//But I need to use the values from the "try"-functions
//and they get thrown away here:
let scoreCards (hand: PokerHand) =
match hand with
| r when (tryStraightFlush hand) <> None -> //prod. Score
| r when (tryFourOfAKind hand) <> None -> //prod. Score
// more code
Instead my code ends up looking like this, and I have to say I don't like this deep nesting.. How can I have a small function for testing each type of configuration, while avoiding a deeply nested if-expressions?
let scoreCards (hand: PokerHand) =
// Too much nesting!
let r = tryStraightFlush hand
if r <> None then
r.Value
else
let r = tryFourOfAKind hand
if r <> None then
r.Value
else
let r = tryFullHouse hand
if r <> None then
r.Value
else
let r = tryFlush hand
if r <> None then
r.Value
else
// nesting continues..