Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- -- Reverse Polish Notation (v1.0.0, a newbie's script :D)
- import qualified Data.Char as C
- rpn :: String -> String
- rpn expr = let res = calc [] $ words expr
- in show $ (if length res == 1 then head else last) res
- where
- isOper = (`elem` ["+","-","*","/","^"])
- isNum = all (== True) . map (C.isNumber)
- calc l [] | length l == 1 = l
- | otherwise = ["There aren't sufficient operators."]
- calc l (x:xs) | isOper x = if length l >= 2
- then if (x == "/") && (ultimate == 0)
- then ["Division by zero"]
- else calc (operate x) xs
- else ["There aren't sufficient operands."]
- | isNum x = calc (push x l) xs
- | otherwise = ["There are tokens which aren't numbers or operators."]
- where
- operate "+" = push (show $ penultimate + ultimate) begin
- operate "-" = push (show $ penultimate - ultimate) begin
- operate "*" = push (show $ penultimate * ultimate) begin
- operate "/" = push (show $ penultimate / ultimate) begin
- operate "^" = push (show $ penultimate ^ (read $ show penultimate :: Int)) begin
- begin = init $ init l
- ultimate = read $ last l :: Float -- because we cannot use the identifier 'last', so it's similar to 'penultimate'
- penultimate = read (last $ init l) :: Float
- push n = (++ [n])
- -- INPUT BUG: power operator generates an error. Use the function directly and not this 'main' block.
- main :: IO()
- main = do
- putStr ">> "
- n <- (readLn :: IO String)
- if (/= "EXIT") (map (C.toUpper) n)
- then do
- putStrLn $ "Result: " ++ (rpn n)
- mainrpn
- else putStrLn "End."
Advertisement
Add Comment
Please, Sign In to add comment