Clock.hs (2519B)
1 {-# OPTIONS_GHC -Wall #-} 2 {-# LANGUAGE OverloadedStrings #-} 3 4 import qualified Data.Map.Strict as MS 5 import Data.Monoid ((<>), mconcat) 6 import qualified Data.Text as T 7 import qualified Data.Text.IO as TIO 8 import System.Environment (getArgs) 9 10 main :: IO () 11 main = do 12 args <- getArgs 13 let parsed = case args of 14 (input : _) -> parse (T.pack input) 15 _ -> Nothing 16 17 case parsed of 18 Nothing -> do 19 TIO.putStrLn "usage: ./clock HH:MM" 20 TIO.putStrLn "(where HH in 00 -- 23, MM in 00 -- 59)" 21 22 Just time -> 23 TIO.putStrLn time 24 25 parse :: T.Text -> Maybe T.Text 26 parse input = case T.splitOn ":" stripped of 27 [hrs, mins] -> do 28 (rhrs, am) <- MS.lookup hrs hourmap 29 rmin <- MS.lookup mins minutemap 30 return (present (rhrs, rmin, am)) 31 32 _ -> Nothing 33 34 where 35 stripped = T.strip input 36 37 hourmap :: MS.Map T.Text (T.Text, Bool) 38 hourmap = MS.fromList (zip hours rhours) 39 40 minutemap :: MS.Map T.Text T.Text 41 minutemap = MS.fromList (zip minutes rminutes) 42 43 present :: (T.Text, T.Text, Bool) -> T.Text 44 present (h, m, am) = "It's " <> h <> " " <> mins <> meridiem where 45 mins 46 | m == T.empty = m 47 | otherwise = m <> " " 48 meridiem 49 | am = "am" 50 | otherwise = "pm" 51 52 onesAndTens :: [T.Text] 53 onesAndTens = [ 54 "one", "two", "three", "four", "five", "six", "seven", "eight", "nine" 55 , "ten", "eleven", "twelve", "thirteen", "fourteen", "fifteen" , "sixteen" 56 , "seventeen", "eightteen", "nineteen" 57 ] 58 59 gentext :: T.Text -> T.Text -> [T.Text] 60 gentext leader prefix = mconcat [ 61 [leader] 62 , fmap ((prefix <> " ") <>) (take 9 onesAndTens) 63 ] 64 65 hours :: [T.Text] 66 hours = 67 [ "00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "10" , "11" 68 , "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22" , "23" 69 ] 70 71 rhours :: [(T.Text, Bool)] 72 rhours = mconcat 73 [ ("twelve", True) : zip hrs (repeat True) 74 , ("twelve", False) : zip hrs (repeat False) 75 ] 76 where 77 hrs = take 11 onesAndTens 78 79 minutes :: [T.Text] 80 minutes = mconcat [ 81 fmap ("0" <>) digs 82 , fmap ("1" <>) digs 83 , fmap ("2" <>) digs 84 , fmap ("3" <>) digs 85 , fmap ("4" <>) digs 86 , fmap ("5" <>) digs 87 ] 88 where 89 digs = fmap render ([0..9] :: [Int]) 90 91 render :: Show a => a -> T.Text 92 render = T.pack . show 93 94 rminutes :: [T.Text] 95 rminutes = mconcat [ 96 gentext "" "oh" 97 , drop (9 :: Int) onesAndTens 98 , gentext "twenty" "twenty" 99 , gentext "thirty" "thirty" 100 , gentext "forty" "forty" 101 , gentext "fifty" "fifty" 102 ] 103