FizzBuzz in Haskell [pdf]
themonadreader.files.wordpress.com
themonadreader.files.wordpress.com
<https://codegolf.stackexchange.com/questions/215216/high-thr...>
<https://github.com/orent/htfizzbuzz/blob/master/fizzbuzz.S>
https://news.ycombinator.com/item?id=29031488
(1260 points, 256 comments)
p.s. It's actually 55GiB/s, aka 59GB/s :)
> "Outputting fizzbuzz should be done by executing the (one and only) piece of code that outputs fizz, followed by the (one and only) piece that outputs buzz. That is because fizzing and buzzing are two separate activities – consider the FizzBuzzHissHowl problem, where hiss and howl are printed for multiples of 7 and 11 respectively. The program design of Exhibit A and B would lead to an explosion of code complexity."
... but always got voted off the island in favor of Exhibit A.
Unclear to me why the canonically correct answer examples for various languages are almost universally mistaken as described there, and yet so fiercely defended!
Perhaps Exhibit C is like Fight Club, to be kept hush hush as a shibboleth for sussing out Principal Engineers?
fizzbuzz n = (test 3 "fizz" . test 5 "buzz") id (show n) where
test d s x = if n `mod` d == 0 then const (s ++ x "") else x
main = mapM_ (putStrLn . fizzbuzz) [0..100]
you can compile with ghc and run... fizzbuzz n = go id (show n)
where
go = test 3 "fizz" . test 5 "buzz"
test d s x =
if n `mod` d == 0
then const (s ++ x "")
else xIf both tests fail, return the 'id' (identity) function which when applied to (show n) will return the number as a string.
If one or both tests succeed, return a 'const' function which will simply return the appropriate string and ignore the (show n).
This example was illuminating. It helped me realize I'm wasting too much time with Haskell.
It's very solvable in Java, as we see here: https://github.com/EnterpriseQualityCoding/FizzBuzzEnterpris...
If a second problem asks you to write something for "FizzBuzzHissHowl", then you can start introducing more code complexity.
As a novice ( but really interested) in functional programming, I had a bit of troubles with Haskell and eventually didn't find something I could do to toy with it.
This paper is basically what I want to try doing in functional programming : almost write maths, but that does the computation.
It wasn't too complex either !
Can someone point me to other resources in the same genre ?
For something more practical, but in PureScript, this e-book has tons of examples and detailed explanations (most concepts translate to Haskell) https://jordanmartinez.github.io/purescript-jordans-referenc...
> Functional programmers! Remember higher-order functions!
I didn't realise utilising HoF meant rolling your own interpreter ;).
Pure FP is very interesting, but having to write entirely without side-effects would be a real challenge for me. I use js+ramda[0], we effectively write our services as a `pipe`, you just stick in transforming fns whereever you need to, e.g.:
const handler = pipe(
fn1,
fn2,
fn3
)(event)
The underlying implementation of `fn1` for example doesn't need to be written in an fp paradigm, it can be written imperatively. You could then slowly-slowly chop out the imperative functions for fp ones if you really wanted, but IMHO some problems are best solved imperatively.My advice is instead: "Programmers! Remember to use the right tool for the job!"
FizzBuzz can be done more "normally" in Haskell with similar levels of simplicity as non-FP languages: https://wiki.haskell.org/Fizzbuzz
People who miss that are clearly looking hard for some reason to dismiss the work.
Haskell isn't ill-suited for something like fizzbuzz at all, it's just _also_ suited for things like quickly writing interpreters and solving problems that way when it makes sense.
Why doesn't C#, Java, etc have the same problem with perception because they have the same "many ways" to solve problems.
"fun"
brainfuck is fun too and no one uses it.
Haskell is simple even if unfamiliar to you. Brainfuck is complex even if familiar to you.
I would actually swap these two descriptions. Haskell is complex, because it has many "complications" (in the sense of features). But those complications permit simple programs. Brainfuck is simple, it has few complications (only 8 instructions) but this forces complications into the programs written in it.
Simplicity is also "how many things" it takes to express an idea or do a useful thing.
In many ways, written Chinese is simpler than written English.
This seems very elegant and clean and I don’t know the slightest bit of Haskell other than “MONADS!!!”
My version looks like the below. I didn't originate the approach but I like this spelling. It won't make total sense to non-Haskellers though.
{-# LANGUAGE MonadComprehensions #-}
import Data.Maybe
import Data.Monoid
fizz :: Int -> String
fizz n = fromMaybe (show n) $ f 3 "Fizz" <> f 5 "Buzz"
where
f :: Int -> String -> Maybe String
f d msg = [msg | n`rem`d == 0]
main = mapM_ putStrLn [fizz n | n <- [1..100]]
This extends in an obvious way to FizzBuzzHissHowl, lets the Monoid instance manage concatenating the special tokens together while remembering if any of the rules have matched, and uses a monad comprehension on the Maybe monad to cleanly lift the token into the Maybe monad if the number is a multiple of whatever. The type annotation on f is added to make it a little bit clearer what is going on.The use of monoids and the monad comprehension may be slightly flashy, but the use of Maybe to remember whether a rule has triggered is second nature in Haskell.
> Exhibit A, in some cases, performs the ‘mod‘ 3 and ‘mod‘ 5 tests more than once
Isn't Haskell a language with controlled side-effects? Compiler ought to see that the same operation is performed twice and factor it out. There are no mutable variables in the scope.
Yes but the trouble is when Haskell does optimisations, it's criticised for having unpredictable performance characteristics.