I think your implementation is fine. I might write it like this, because I find it more idiomatic in F# to avoid guards (when
clauses) in pattern matching where a guard free implementation is equally concise.
let fizzbuzz x =
match (x % 5, x % 3) with
| (0, 0) -> "FizzBuzz"
| (0, _) -> "Buzz"
| (_, 0) -> "Fizz"
| _ -> string x
[1..100] |> List.map fizzbuzz |> List.iter (printfn "%s")
There are ways you can make this more elaborate / extensible but while that can be an interesting exercise I don't think they're really an improvement over a simple straightforward implementation like this.