from Hacker News

FizzBuzz Through Monoids

by kqr on 5/23/25, 11:46 AM with 4 comments

  • by throwaway81523 on 5/26/25, 5:49 PM

    Code is a little too fancy though it's easy to fall into that temptation with Haskell. Particularly though, using the Monoid instance on strings ties you to concatenating the strings together. There was an example the other day where the strings had to be separated by spaces and terminated by an exclam point ("Fizz Buzz!"). My solution used lists straightforwardly instead of Monoids. It goes to 110 instead of 100 since 105 is 3*5*7.

        import           Data.List (intercalate)
    
        fizzle :: Int -> String
        fizzle n =
            let ws = [(3,"Fizz"),(5,"Buzz"),(7,"Bazz")]
                a = [s | (d,s) <- ws, n`rem`d == 0]
            in case a of []        -> show n
                         otherwise -> intercalate " " a ++ "!"
    
        main = mapM_ (putStrLn . fizzle) [1..110]
  • by theamk on 6/1/25, 6:01 AM

    it always amazes me how Haskell uses the very complex approaches for a very simple problem. Do you want a design that generalizes to zork? Here it is:

        def fizzbuzz(i):
            return "".join((["fizz"] if (i % 3) == 0 else []) + 
                           (["buzz"] if (i % 5) == 0 else [])
                          ) or str(i)
     
        for i in range(1, 101):
            print(fizzbuzz(i))
    
    here is "indication of good modularity" with no monoid in sight, and we did not have to import 3 extra libraries either.
  • by lgas on 5/26/25, 5:19 PM

    I wrote a similar implementation a while back[1]. The major difference is that mine only allows rules of the form "n is divisible by m" whereas the one from the post allows arbitrary predicates over n. Wouldn't be that hard to update though.

    [1] https://gist.github.com/lgastako/d4fa392cbe85cbfae7dfa5e18c1...