F# by example: FizzBuzz kata rivisited - More on Pattern-Matching
Contents
In the first post of this series we've seen a possible implementation for the FizzBuzz kata. In particular, we've finished the article with this code for the fizzBuzz function:
https://gist.github.com/vgaltes/edafb6efc55273543a1d
We've applied a Tuple pattern to match the tuple created in the match part. We've also applied Wildcard matching to discard the values we are not interested in.
In this article we're going to see how we can solve this problem using another flavors of Pattern-Matching.
Active patterns
Using active patterns you can define case names (partitions of your data) so that you can use these names in Pattern-Matching expressions. A typical example could be this one:
https://gist.github.com/vgaltes/ea700e4c7f2334223d0a
So let's use active pattern to resolve FizzBuzz kata. The active pattern could be something like this:
https://gist.github.com/vgaltes/ac693fc6a81885d7eed8
As you can see we have an active recognizer that defines four cases. Inside the recognizer we're using Pattern-Matching to select the appropriate case as we did in the original implementation of the kata. Now, we just have to use this recognizer in a Pattern-Matching function:
https://gist.github.com/vgaltes/2aa85a0ef5e92d4dfd97
As you can see, we are using a Pattern-Matching function, a convenient shortcut for creating a Pattern-<atching lambda expression. We are just replacing the match...with portion of the match expression with function.
Now, if we would like to print the first 100 numbers we can do something like this:
https://gist.github.com/vgaltes/1bd24d3819c9e6022514
In this case we are using a range expression to create a sequence with numbers from 1 to 100. Using the pipe forward operator we are passing this sequence to the map function of the Seq module that transforms a sequence applying a function (in this case fizzBuzz) to every element in a sequence. Finally, we iterate over the sequence to print the results.
Partial Active Patterns
Active patterns have to limitations:
- Each input must map to a named case.
- Are limited to seven named cases.
An alternative to active patterns are partial active patterns. A partial active pattern include only a single case name followed by an underscore. Let's rewrite the FizzBuzz kata using partial active patterns.
First, we have to write the active patterns we are going to use:
https://gist.github.com/vgaltes/06f0e841f0a82d9d7d8c
And after that, we are ready to use them in a Pattern-Matching expression:
https://gist.github.com/vgaltes/ba40cc99e15118b81301
Parameterized Active Patterns
It's possible to use a function that accepts more than the match value. Let's define a Parameterized partial active pattern (remember to include additional parameters before the match input argument.
https://gist.github.com/vgaltes/e453ddd088beac84791f
And now, let's use this partial active pattern:
https://gist.github.com/vgaltes/8c1c7b58c07df88bfd3a
And that's all for today. All these samples are extracted from the excellent book The book of F#, so I can't recommend it enough if you want to learn F#.
As usual, I'm just learning F#. If you see something incorrect or you want to add an alternative solution, please leave a comment.
Author Vicenç García
LastMod 10-05-2015