Advertisement
Guest User

Untitled

a guest
Nov 21st, 2014
152
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. module Main where
  2.  
  3. import Control.Concurrent
  4. import Data.Time
  5. import Data.Time.LocalTime
  6. import System.Process
  7.  
  8. ------------------------------------------------------------------------------------------------------------------------
  9. -- Interface
  10. ------------------------------------------------------------------------------------------------------------------------
  11. -- | Clock digit.
  12. data ClockDigit = Colon | Zero | One | Two | Three | Four | Five | Six | Seven | Eight | Nine
  13.                   deriving (Eq, Ord, Show)
  14.  
  15. -- | Clock digit as ASCII text, split across three lines.
  16. type AsciiDigit = (String, String, String)
  17.  
  18. -- | Generate AsciiDigit from ClockDigit.
  19. digitToAscii :: ClockDigit -> AsciiDigit
  20. digitToAscii Colon = ("   ", " . ", " . ")
  21. digitToAscii Zero  = (" _ ", "| |", "|_|")
  22. digitToAscii One   = ("   ", " | ", " | ")
  23. digitToAscii Two   = (" _ ", " _|", "|_ ")
  24. digitToAscii Three = ("_  ", "_| ", "_| ")
  25. digitToAscii Four  = ("   ", "|_|", "  |")
  26. digitToAscii Five  = (" _ ", "|_ ", " _|")
  27. digitToAscii Six   = (" _ ", "|_ ", "|_|")
  28. digitToAscii Seven = (" _ ", "  |", "  |")
  29. digitToAscii Eight = (" _ ", "|_|", "|_|")
  30. digitToAscii Nine  = (" _ ", "|_|", "  |")
  31.  
  32. -- | Generate AsciiDigits from ClockDigits.
  33. digitsToAscii :: [ClockDigit] -> [AsciiDigit]
  34. digitsToAscii []     = []
  35. digitsToAscii (d:ds) = digitToAscii d : digitsToAscii ds
  36.  
  37. -- | Get one of the line components from an AsciiDigit.
  38. getAsciiDigitLn :: Int -> AsciiDigit -> String
  39. getAsciiDigitLn 0 (x,_,_) = x
  40. getAsciiDigitLn 1 (_,x,_) = x
  41. getAsciiDigitLn 2 (_,_,x) = x
  42. getAsciiDigitLn _ _       = error "Line number must be [0,3)"
  43.  
  44. -- | Get one of the line components from a list of AsciiDigits.
  45. getAsciiDigitsLn :: Int -> [AsciiDigit] -> String
  46. getAsciiDigitsLn i []     = []
  47. getAsciiDigitsLn i (d:ds) = (getAsciiDigitLn i d) ++ (getAsciiDigitsLn i ds)
  48.  
  49. -- | Merge a list of AsciiDigits into a single AsciiDigit.
  50. mergeAsciiDigits :: [AsciiDigit] -> AsciiDigit
  51. mergeAsciiDigits ds = (getAsciiDigitsLn 0 ds, getAsciiDigitsLn 1 ds, getAsciiDigitsLn 2 ds)
  52.  
  53. -- | Fold an AsciiDigit into a single string.
  54. asciiDigitToStr :: AsciiDigit -> String
  55. asciiDigitToStr (l0, l1, l2) = l0 ++ "\n" ++ l1 ++ "\n" ++ l2
  56.  
  57. -- | Fold a list of AsciiDigit into a single string.
  58. asciiDigitsToStr :: [AsciiDigit] -> String
  59. asciiDigitsToStr [] = []
  60. asciiDigitsToStr ds = asciiDigitToStr $ mergeAsciiDigits ds
  61.  
  62. -- | Generate a list of ClockDigits from a number.
  63. numberToDigits' :: Int -> [ClockDigit]
  64. numberToDigits' 0 = []
  65. numberToDigits' x
  66.    | r == 9    = numberToDigits' (x `div` 10) ++ [Nine]
  67.     | r == 8    = numberToDigits' (x `div` 10) ++ [Eight]
  68.    | r == 7    = numberToDigits' (x `div` 10) ++ [Seven]
  69.     | r == 6    = numberToDigits' (x `div` 10) ++ [Six]
  70.    | r == 5    = numberToDigits' (x `div` 10) ++ [Five]
  71.     | r == 4    = numberToDigits' (x `div` 10) ++ [Four]
  72.    | r == 3    = numberToDigits' (x `div` 10) ++ [Three]
  73.     | r == 2    = numberToDigits' (x `div` 10) ++ [Two]
  74.    | r == 1    = numberToDigits' (x `div` 10) ++ [One]
  75.     | r == 0    = numberToDigits' (x `div` 10) ++ [Zero]
  76.    | otherwise = undefined
  77.                  where r = x `mod` 10
  78.  
  79. -- | Generate a list of ClockDigits from a number, padding with zeros where necessary.
  80. numberToDigits :: Int -> [ClockDigit]
  81. numberToDigits x
  82.    | n == 0    = Zero : Zero : y
  83.    | n == 1    = Zero : y
  84.    | otherwise = y
  85.    where y = numberToDigits' x
  86.           n = length y
  87.  
  88. -- | Generate a list of ClockDigits from a time triple.
  89. timeToDigits :: (Int,Int,Int) -> [ClockDigit]
  90. timeToDigits (h,m,s)  = (numberToDigits h) ++ (Colon : numberToDigits m) ++ (Colon : numberToDigits s)
  91.  
  92. -- | Generate a list of AsciiDigits from a time triple.
  93. timeToAscii t = digitsToAscii $ timeToDigits t
  94.  
  95. -- | Generate a string from a time triple.
  96. timeToStr :: (Int,Int,Int) -> String
  97. timeToStr t = asciiDigitsToStr $ timeToAscii t
  98.  
  99. -- | Print a time triple as a string.
  100. putTime :: (Int,Int,Int) -> IO ()
  101. putTime t = putStrLn $ timeToStr t
  102.  
  103. ------------------------------------------------------------------------------------------------------------------------
  104. -- Clock
  105. ------------------------------------------------------------------------------------------------------------------------
  106. -- | Get the time of day as a triple (hours, minutes, seconds).
  107. getTimeTriple :: IO (Int,Int,Int)
  108. getTimeTriple = do
  109.     t <- fmap (fromRational . timeOfDayToDayFraction . localTimeOfDay . zonedTimeToLocalTime) getZonedTime
  110.     let h = t * 24
  111.         m = (h - fromIntegral (truncate h)) * 60
  112.         s = (m - fromIntegral (truncate m)) * 60
  113.     return (truncate h,truncate m,truncate s)
  114.  
  115. ------------------------------------------------------------------------------------------------------------------------
  116. -- Main
  117. ------------------------------------------------------------------------------------------------------------------------
  118. -- | Sleep for a number of seconds.
  119. sleep :: Int -> IO ()
  120. sleep s = threadDelay $ s * 1000000
  121.  
  122. -- | Whether to use system("clear") [True] or system("cls") [False]
  123. unix :: Bool
  124. #ifdef mingw32_HOST_OS
  125. unix = False
  126. #else
  127. unix = True
  128. #endif
  129.  
  130. -- | Main function.
  131. main :: IO ()
  132. main = do
  133.     t <- getTimeTriple
  134.     system $ if unix then "clear" else "cls"
  135.     putTime t
  136.     sleep 1
  137.     main
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement