Teatimer in Haskell

Posted May 5, 20:46

I've been learning Haskell lately which means it is time to rewrite my tea timer again.

The biggest challenge in writing the Haskell version was playing an alarm sound. The Haskell sound libraries are a little complex when all you need is a 1-second sound.

I've also switched to Linux since the last time I rewrote the tea timer. Linux's overuse of system beep means that I have it muted (ruling it out as an alarm).

Ultimately I ended up just calling paplay. Not the most portable solution but it works for my use case.

import Control.Concurrent (threadDelay)
import System.Environment(getArgs)
import Data.Time.Clock
import System.IO
import System.Process
import System.Console.ANSI

sleep :: Int -> Int -> IO ()
sleep 0   0   = return ()
sleep min sec = 
    putStr ((formatTime min sec) ++" \r") >>
    hFlush stdout >>
    threadDelay (1000000) >>
    if sec == 0
    then sleep (min - 1) 59
    else sleep min (sec - 1)

main = do 
    args <- getArgs
    hideCursor
    sleep (read $ args !! 0) (read $ args !! 1)
    showCursor
    createProcess (proc "paplay" ["/home/chris/.teatimer/alarm.ogg"])
          
formatTime :: Int -> Int -> String
formatTime min sec = 
    (show min) ++ ":" ++ (padIntString (show sec))

padIntString :: String -> String
padIntString str = 
    if ((tail str) == "")
    then '0' : str
    else str