Data hosted with ♥ by Pastebin.com - Download Raw - See Original
  1. {-# LANGUAGE LambdaCase #-}
  2. module Main where
  3.  
  4. import Control.Monad
  5. import System.IO
  6.  
  7. {-@ data NumberType = Normal (i :: {v:Int | v mod 3 /= 0 && v mod 5 /= 0})
  8.                     | Fizz
  9.                     | Buzz
  10.                     | FizzBuzz @-}
  11.  
  12. data NumberType = Normal Int
  13.                 | Fizz
  14.                 | Buzz
  15.                 | FizzBuzz
  16.  
  17. {-@ fizz :: {v:Int | v mod 3 == 0 && v mod 5 /= 0} -> NumberType @-}
  18. fizz :: Int -> NumberType
  19. fizz _ = Fizz
  20.  
  21. {-@ buzz :: {v:Int | v mod 3 /= 0 && v mod 5 == 0} -> NumberType @-}
  22. buzz :: Int -> NumberType
  23. buzz _ = Buzz
  24.  
  25. {-@ fizzbuzz :: {v:Int | v mod 3 == 0 && v mod 5 == 0} -> NumberType @-}
  26. fizzbuzz :: Int -> NumberType
  27. fizzbuzz _ = FizzBuzz
  28.  
  29. numberType :: Int -> NumberType
  30. numberType i = case (i `mod` 3 == 0, i `mod` 5 == 0) of
  31.   (True, False) -> fizz i
  32.   (False, True) -> buzz i
  33.   (True, True) -> fizzbuzz i
  34.   _ -> Normal i
  35.  
  36. main :: IO ()
  37. main = do
  38.   putStrLn "FizzBuzz v. 1.0.0"
  39.   putStr "From: "
  40.   hFlush stdout
  41.   from <- getLine
  42.   putStr "To: "
  43.   hFlush stdout
  44.   to <- getLine
  45.   forM_ (map numberType [read from .. read to]) $ \case
  46.     Normal i -> putStrLn $ show i
  47.     Fizz -> putStrLn "Fizz"
  48.     Buzz -> putStrLn "Buzz"
  49.     FizzBuzz -> putStrLn "FizzBuzz"