An if/elif/else
expression can be used to conditionally execute logic. F# also has another, more powerful way to conditionally execute logic: pattern matching. With pattern matching, a value can be tested against one or more patterns. An example of such a pattern is the constant pattern, which matches a value against a constant (e.g. 1
or "hello"
).
In F#, pattern matching is done through the match
keyword:
let describe number =
match number with
| 0 -> "Zero"
| 1 -> "One"
While this may look like switch
statements in other languages, pattern matching starts to shine when also using other patterns. One such pattern is the variable pattern, which allows one to capture a value:
match number with
| 0 -> "Zero"
| i -> sprintf "Non zero: %d" i
In some cases, you may want to add an additional condition to a pattern. This is known as a guard (clause), which can be added using the when
keyword:
match number with
| 0 -> "Zero"
| i when i < 0 -> "Negative number"
In the above example, not all possible input will have a matching pattern. The compiler will detect this and output a warning. This is known as exhaustive checking. To solve the warning, one has to handle all cases. For this, the wildcard pattern can be used, which is a pattern that matches on any value:
match number with
| i when i < 0 -> "Negative number"
| _ -> "Positive number"
// No compiler warning
Pattern matching will test a value against each pattern from top to bottom, until it finds a matching pattern and executes the logic associated with that pattern. The order of patterns matters!
In this exercise, you are playing a number guessing game with a friend. The rules are simple: you secretly choose a number between 1
and 100
and your friend tries to guess what number you've chosen. To help your friend, you respond differently depending on how close the guess was to the number you've chosen (42
). These are the rules for the different replies:
42
: "Correct"41
or 43
: "So close"41
: "Too low"43
: "Too high"You have four tasks to encode the replies to the guesses.
Implement the reply
function to reply to a correct guess:
reply 42
// => "Correct"
Modify the reply
function to reply to close guesses:
reply 41
// => "So close"
Modify the reply
function to reply to too low guesses:
reply 25
// => "Too low"
Modify the reply
function to reply to too high guesses:
reply 88
// => "Too high"
Sign up to Exercism to learn and master F# with 15 concepts, 134 exercises, and real human mentoring, all for free.