Skip to content

Instantly share code, notes, and snippets.

@Rembane
Last active October 3, 2022 20:31
Show Gist options
  • Save Rembane/03be70499a511012922b0b5f409af953 to your computer and use it in GitHub Desktop.
Save Rembane/03be70499a511012922b0b5f409af953 to your computer and use it in GitHub Desktop.
module Main where
{-|
Module : Main
Description : A Reversed Polish Notation interpreter
A naive implementation implemented as a proof of concept. Among the possible future work is:
- Error checking more advanced than just crashing.
- A translator to infix notation.
- A translator from infix notation.
- Variables?
-}
import Control.Monad (forever)
import Data.Char (isDigit)
import Data.List (all, words)
example = "1 1 + 2 + 3 + 4 + 5 +"
data RPN
= RInt Int
| RAdd
| RMul
| RSub
| RDiv
deriving (Show)
parse :: String -> [RPN]
parse = map go . words
where
go "+" = RAdd
go "*" = RMul
go "-" = RSub
go "/" = RDiv
go cs
| all isDigit cs = RInt (read cs)
| otherwise = error $ "What is this?! " <> show cs
rpn :: [RPN] -> Int
rpn (RInt i1 : RInt i2 : op : rest) =
let result = case op of
RAdd -> i1 + i2
RMul -> i1 * i2
RSub -> i1 - i2
RDiv -> div i1 i2
in case rest of
[] -> result
_ -> rpn (RInt result : rest)
main :: IO ()
main = forever $ do
putStr "> "
i <- rpn . parse <$> getLine
print i
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment