Haskell Hacking: a journal of Haskell programming

Haskell Hacking has moved => Go here.
2006-11-12

More refactoring

jcreigh wrote on his RPN calculator in Haskell. Here's some refactoring for fun (adding StateT and readline, mostly).
import Data.Char
import Data.Maybe
import System.Console.Readline
import System.Exit
import System.IO
import Control.Monad.State
import qualified Data.Map as M

type Stack      = [Double]
type Operator   = Stack -> Stack

forever a = a >> forever a
io        = liftIO

main = runStateT (forever repl) []

repl = do
    m <- io $ readline "> "
    case m of
        Nothing -> io $ exitWith ExitSuccess
        Just l  -> do modify $ flip eval (parse l)
                      io . print =<< get

eval = foldl (flip id)

parse = map parse' . words

parse' t | Just op <- M.lookup t table = op
         | otherwise                   = (read t :)

table = M.fromList
    [("+"    , binaryOp (+)         )
    ,("-"    , binaryOp (-)         )
    ,("*"    , binaryOp (*)         )
    ,("/"    , binaryOp (/)         )
    ,("**"   , binaryOp (**)        )
    ,("log"  , unaryOp log          )
    ,("sqrt" , unaryOp sqrt         )
    ,("dup"  , \(x:xs)   -> x:x:xs  )
    ,("swap" , \(a:b:xs) -> b:a:xs  )
    ,("pop"  , tail                 )]

unaryOp  f (a:s)   = f a : s
binaryOp f (a:b:s) = f b a : s

/home :: /haskell :: permalink :: rss

Response to "Getting real with Haskell"

Magnus wrote about his beginning steps in Haskell. Here's a quick refactor of the code, for fun, mostly:
import Data.Either
import MissingH.Time.ParseDate
import System.Environment
import System.Locale
import System.Time

diffAndToString s e = formatTimeDiff defaultTimeLocale "%R" diff
    where diff = normalizeTimeDiff $ diffClockTimes (toClockTime s) (toClockTime e)

calcDiff start end = case (parse start, parse end) of
    (Nothing, _)     -> Left "start time"
    (_, Nothing)     -> Left "end time"
    (Just s, Just e) -> Right $ diffAndToString s e
  where parse = parseCalendarTime defaultTimeLocale "%C%y%m%d-%H%M"

resultString [s,e] = either ("Bad "++) id (calcDiff s e)

main = putStrLn . resultString =<< getArgs

/home :: /haskell :: permalink :: rss

About

Real World Haskell

RWH Book Cover

Archives

Recommended

Blog Roll

Syndicate