5
\$\begingroup\$

I run a coding dojo at work. For one session I'm to showing that you can use a kata to get into a new language.

I'm using the FizzBuzz Kata to to show F# (and JavaScript) because it is short. The problem is I am very new to F# and find myself devolving to objects instead of being functional.

Thus, I would like to see better ways of doing this (using nunit):

namespace FizzBuzzFSharp
    open NUnit.Framework

    module FizzBuzzer = 
        let FizzBuzz number = 
            match number with 
            | i when i % 3 = 0 && i % 5 = 0 -> "FizzBuzz"
            | i when i % 5 = 0 -> "Buzz"
            | i when i % 3 = 0 -> "Fizz"
            | _ -> number.ToString()


        [<Test>]
        [<TestCase(1, "1")>]
        [<TestCase(2, "2")>]
        [<TestCase(3, "Fizz")>]        
        [<TestCase(4, "4")>]
        [<TestCase(5, "Buzz")>]
        [<TestCase(6, "Fizz")>]
        [<TestCase(7, "7")>]
        [<TestCase(8, "8")>]
        [<TestCase(9, "Fizz")>]
        [<TestCase(10, "Buzz")>]
        [<TestCase(11, "11")>]
        [<TestCase(12, "Fizz")>]
        [<TestCase(13, "13")>]        
        [<TestCase(14, "14")>]
        [<TestCase(15, "FizzBuzz")>]        
        [<TestCase(30, "FizzBuzz")>]
        let WhenNumber_ThenResult(number, expected) = 
            Assert.AreEqual(expected, FizzBuzz(number));
\$\endgroup\$
  • \$\begingroup\$ Sister question: codereview.stackexchange.com/questions/64869/… \$\endgroup\$ – Vogel612 Oct 6 '14 at 13:49
  • \$\begingroup\$ Here's how I did it: blog.ploeh.dk/2012/07/20/FizzBuzzkatainFstage1 \$\endgroup\$ – Mark Seemann Oct 6 '14 at 16:22
  • \$\begingroup\$ @MarkSeemann I know, your blog was my starting point of reference. As I was not sure how to get [<Theory>] and [<InlineData>] to work, I dropped back to Nunit and Test / TestCase. (once I got the unit testing I did build it up test first, but as you can see from the outcome the details of your solution stuck in my fingers - down to the names and solution pattern) \$\endgroup\$ – Paul Spencer Oct 7 '14 at 11:06
  • \$\begingroup\$ Are you interested primarily in better ways to write the tests or more idiomatic ways to implement the function itself? \$\endgroup\$ – mattnewport Nov 4 '14 at 7:11
  • \$\begingroup\$ @mattnewport on the rare occasions that I venture into the F# world I find myself leaning on an OO crutch. I quite like the tests, so I'm looking for nice ways to write the F# function. (do you not like the test?) \$\endgroup\$ – Paul Spencer Nov 11 '14 at 18:59
4
\$\begingroup\$

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.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.