{-# LANGUAGE OverloadedStrings #-} module Main (main) where import Prelude import Control.Concurrent (threadDelay) import Data.ByteString (ByteString) import Data.Semigroup ((<>)) import Data.String (fromString) import Numeric.Natural (Natural) import qualified Network.Simple.TCP as Net import qualified Options.Applicative as Opt main :: IO () main = getArgs >>= \args -> Net.serve Net.HostAny (argPort args) accept accept :: (Net.Socket, Net.SockAddr) -> IO () accept (s, _) = go 1 where go i = Net.send s (fizzbuzz i) *> Net.send s "\n" *> threadDelay 500000 *> go (succ i) fizzbuzz :: Natural -> ByteString fizzbuzz i = case (i `mod` 3 == 0, i `mod` 5 == 0) of (True, False) -> "Fizz" (False, True) -> "Buzz" (True, True) -> "Fizz buzz" (False, False) -> fromString (show i) data Args = Args { argPort :: String } getArgs :: IO Args getArgs = Opt.execParser $ Opt.info (Opt.helper <*> argP) (Opt.header "FizzBizz as a service.") argP :: Opt.Parser Args argP = Args <$> portP portP :: Opt.Parser Net.ServiceName portP = Opt.strOption $ Opt.long "port" <> Opt.short 'p' <> Opt.metavar "PORT" <> Opt.help "Service port to bind."