I'm learning F#, and have challenged myself to write a good functional implementation of FizzBuzzWoof. (The difference from standard FizzBuzz is that any number that either is divisible by or contains the appropriate number must be replaced by the appropriate string of text: 3 = Fizz, 5 = Buzz, 7 = Woof. Also, the strings must be printed in that order.)I wrote a version using partial matching that I'm quite happy with, except for the one darn mutable Boolean in there that makes it feel less than functional to me. Is there a way I can get rid of that mutable Boolean, and still have clean code?My attempt so far:module FizzBuzzWoof =    let isDivisibleBy a b = (a % b) = 0    let contains a b = a.ToString().Contains(b.ToString())    let fizzBuzzWoofMatcher n = fun i ->        if isDivisibleBy i n then Some ()        elif contains i n then Some ()        else None    let (|Fizz|_|) i = fizzBuzzWoofMatcher 3    let (|Buzz|_|) i = fizzBuzzWoofMatcher 5    let (|Woof|_|) i = fizzBuzzWoofMatcher 7open FizzBuzzWooflet runme () =    for i = 1 to 100 do        let mutable matched = false  // Want to eliminate this        match i with        | Fizz () -> printf Fizz; matched <- true        | _ -> ()        match i with        | Buzz () -> printf Buzz; matched <- true        | _ -> ()        match i with        | Woof () -> printf Woof; matched <- true        | _ -> ()        if matched        then            printfn         else            printfn %d irunme()I did come up with the idea of replacing the final if matched with another match expression as follows:        match i with        | Fizz () -> printfn         | Buzz () -> printfn         | Woof () -> printfn         | _ -> printfn %d iAnd this would work, but it runs the match functions an extra time. In this case this is absolutely fine since they're all quite fast, but what if I have a match function that takes a long time? Is there a way to run each match function just once, yet still avoid the use of mutable?
FizzBuzzWoof in F#
f#;fizzbuzz
You can avoid using mutable by collecting all matching results and folding them into single bool value.let matchSmth matchFun msg i = match matchFun i with| Some i ->     printf msg    true| None -> falselet matchFizz = matchSmth (fizzBuzzWoofMatcher 3) Fizzlet matchBuzz = matchSmth (fizzBuzzWoofMatcher 5) Buzzlet matchWoof = matchSmth (fizzBuzzWoofMatcher 7) Wooflet runme() =     for i = 1 to 100 do        let matched = [matchFizz i; matchBuzz i; matchWoof i] |> List.fold (||) false        if matched then printfn         else printfn %d i