I'm trying to understand Active Patterns, so I'm playing around with FizzBuzz:
let (|Fizz|_|) i = if i % 3 = 0 then Some Fizz else None
let (|Buzz|_|) i = if i % 5 = 0 then Some Buzz else None
let (|FizzBuzz|_|) i = if i % 5 = 0 && i % 3 = 0 then Some FizzBuzz else None
let findMatch = function
| Some Fizz -> "Fizz"
| Some Buzz -> "Buzz"
| Some FizzBuzz -> "FizzBuzz"
| _ -> ""
let fizzBuzz = seq {for i in 0 .. 100 -> Some i}
|> Seq.map (fun i -> i, findMatch i)
Is this basically the right approach, or is there a better way to use Active Patterns here? Shouldn't I be able to make findMatch
take an int instead of int option?
Your findMatch
function should be:
let findMatch = function
| FizzBuzz -> "FizzBuzz" (* should be first, as pad pointed out *)
| Fizz -> "Fizz"
| Buzz -> "Buzz"
| _ -> ""
You can rewrite the last few lines:
let fizzBuzz = Seq.init 100 (fun i -> i, findMatch i)
Your active patterns are fine. One alternative is to use a complete active pattern:
let (|Fizz|Buzz|FizzBuzz|Num|) i =
match i % 3, i % 5 with
| 0, 0 -> FizzBuzz
| 0, _ -> Fizz
| _, 0 -> Buzz
| _ -> Num i