FizzBuzzをモナドで

書いてみた。

data FB a = FB (a, String)

instance Monad FB where
  return x = FB (x, "") 
  m >>= f  = bind m f 
    where bind (FB (x, y)) f = let FB (m, n) = f x in FB (m, y ++ n)

instance (Show a) => Show (FB a) where
  show (FB (x, "")) = show x
  show (FB (_, y))  = y 

fizzbuzz = mapM_ (\x -> print (fizz x >>= buzz))
  where fizz x | x `mod` 3 == 0 = FB (x, "Fizz")
               | otherwise      = return x
        buzz x | x `mod` 5 == 0 = FB (x, "Buzz")
               | otherwise      = return x