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\$
6
  • \$\begingroup\$ Sister question: codereview.stackexchange.com/questions/64869/… \$\endgroup\$
    – Vogel612
    Commented Oct 6, 2014 at 13:49
  • \$\begingroup\$ Here's how I did it: blog.ploeh.dk/2012/07/20/FizzBuzzkatainFstage1 \$\endgroup\$ Commented Oct 6, 2014 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\$ Commented Oct 7, 2014 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\$ Commented Nov 4, 2014 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\$ Commented Nov 11, 2014 at 18:59

1 Answer 1

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 and acknowledge you have read our privacy policy.

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