Hacker News new | comments | show | ask | jobs | submit login

No where near compact (or possibly obtuse?) enough for a Haskell version, surely? Here's one I found elsewhere on the net sometime ago:

    (~>) :: (Integral a) => a -> String -> a -> Maybe String
    (n ~> str) i = str <$ guard (i `mod` n == 0)

    fizzbuzz = 3~>"Fizz" <> 5~>"Buzz"

    main = mapM_ putStrLn $ catMaybes $ fizzbuzz <$> [1..100]
At least it generalises nicely to arbitrary fizzbuzz numbers! (edit: as noted below this version as written fails to print the non fizzbuzz digits. An exercise for the reader :) )

TBF, I wrote this article 5 years ago. Monad Comprehensions were in fashion at the time.

Now every dang person wants to write an arrow with a tilde in it and exclaim, 'Naturality!' ;)

Gotta love the use of guard in this. Maybe I should revisit.

I suspect there is also a clever way to do this applicatively, but haven't really noodled with it to see if it lines up. Any chance to use applicativeDo!

    main = traverse_ putStrLn $ Compose $ fizzbuzz <$> [1..100]

I did not know about compose and this is a neat find.

I’m sure there's a way to define the main function above in an Applicative fashion, but my Haskell isn't really up to it!

    fizzbuzzbazz = mconcat
      [ 3 ~> "Fizz"
      , 5 ~> "Buzz"
      , 7 ~> "Bazz"
Also, I believe you should have something like

    main = mapM_ putStrLn $ map (fromMaybe . show <*> fizzbuzz) [1..100]
to print out the number when it isn't matched by any of the rules.

Point! I did have something like that in the original version, but was experimenting with other approaches and lost the digits somewhere along the way.

For those who don't speak Haskell, its worth noting that "<>" is the monoid concatenation operator. The "~>" operator returns a function type "a -> Maybe String". A function type is a monoid if its return type is a monoid, so this works.

Guidelines | FAQ | Support | API | Security | Lists | Bookmarklet | Legal | Apply to YC | Contact