4 ms·
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 co
by throwaway81523 1y ago
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]
- kqr 1y agoAnother way to do it would be newtype Words = Words { getWords :: String } instance Semigroup Words where Words a <> Words b = Words (a <> " " <> b) instance Monoid Words where mempty = Words mempty fizzbuzz i = maybe (show i) (<> "!") . fmap getWords . mconcat $ [ Words "fizz" <$ guard (rem i 3 == 0) , Words "buzz" <$ guard (rem i 5 == 0) ] but at this point I agree lists might be more clear.