Skip to content

Instantly share code, notes, and snippets.

@LouiS0616
Created April 17, 2020 07:32
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save LouiS0616/46b77b7d321a285bb592815eefb0a1a8 to your computer and use it in GitHub Desktop.
Save LouiS0616/46b77b7d321a285bb592815eefb0a1a8 to your computer and use it in GitHub Desktop.
逆ポーランド記法電卓 Reverse Polish Notation Calcurator
import Text.Read
import Stack
--
readWithEffort :: Read r => String -> Either String r
readWithEffort src = case readMaybe src of
(Just a) -> Right a
Nothing -> Left src
--
solveRPN :: String -> Double
solveRPN = head . foldl loop [] . map readWithEffort . words
where
loop :: Stack Double -> Either String Double -> Stack Double
loop stack (Left operator) = push newStack $ case operator of
"+" -> operand1 + operand2
"-" -> operand1 - operand2
"*" -> operand1 * operand2
_ -> error "invalid operator"
where
(operand2, stack') = pop stack
(operand1, newStack) = pop stack'
loop stack (Right num) = push stack num
--
main :: IO()
main = print $ solveRPN "10 4 3 + 2 * -"
module Stack(
Stack, pop, push
) where
--
type Stack a = [a]
pop :: Stack a -> (a, Stack a)
pop stack = (e, newStack)
where
e = last stack
newStack = init stack
push :: Stack a -> a -> Stack a
push stack e = newStack
where
newStack = stack ++ [e]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment