I'm reading through Write Yourself a Scheme after finishing going through Learn You a Haskell. I attempted one of the early exercises: writing a program to get an operator and two numbers and do a computation. It works fine.
Things I would like to know:
How should I structure a program, in terms of building larger functions out of smaller functions? Are there redundancies in my code?
What's the most effective way to use the Maybe type to indicate failure when main is of type
IO ()? Is my
checkSuccess an appropriate way to do this?
module Main where import System.Environment -- parses the first arithmetic operator in a string parseOperator :: String -> Maybe Char parseOperator  = Nothing parseOperator (x:xs) | x == '*' = Just '*' | x == '/' = Just '/' | x == '+' = Just '+' | x == '-' = Just '-' | otherwise = parseOperator xs parseNum :: String -> Maybe Double parseNum x = let parsed = reads x :: [(Double,String)] in case parsed of [(a,"")] -> Just a [(_,_)] -> Nothing  -> Nothing compute :: Maybe Char -> Maybe Double -> Maybe Double -> Maybe Double compute Nothing _ _ = Nothing compute _ Nothing _ = Nothing compute _ _ Nothing = Nothing compute (Just c) (Just x) (Just y) | c == '*' = Just $ x * y | c == '/' = Just $ x / y | c == '+' = Just $ x + y | c == '-' = Just $ x - y checkSuccess :: Maybe Double -> IO () checkSuccess Nothing = putStrLn "Failed. Check correctness of inputs" checkSuccess (Just r) = putStrLn $ "Result: " ++ (show r) runSequence :: String -> String -> String -> IO () runSequence os xs ys = checkSuccess $ compute (parseOperator os) (parseNum xs) (parseNum ys) main = do putStrLn "Enter operator: * / + -" operator <- getLine putStrLn "Enter first number" first <- getLine putStrLn "Enter second number" second <- getLine runSequence operator first second