module Problems.Monads (Operator (..), Element (..), parsePostfix) where
import Data.Char (isDigit)
data Operator
= Negate
| Add
| Subtract
| Multiply
| Divide
| Modulo
deriving (Operator -> Operator -> Bool
(Operator -> Operator -> Bool)
-> (Operator -> Operator -> Bool) -> Eq Operator
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Operator -> Operator -> Bool
== :: Operator -> Operator -> Bool
$c/= :: Operator -> Operator -> Bool
/= :: Operator -> Operator -> Bool
Eq, Int -> Operator
Operator -> Int
Operator -> [Operator]
Operator -> Operator
Operator -> Operator -> [Operator]
Operator -> Operator -> Operator -> [Operator]
(Operator -> Operator)
-> (Operator -> Operator)
-> (Int -> Operator)
-> (Operator -> Int)
-> (Operator -> [Operator])
-> (Operator -> Operator -> [Operator])
-> (Operator -> Operator -> [Operator])
-> (Operator -> Operator -> Operator -> [Operator])
-> Enum Operator
forall a.
(a -> a)
-> (a -> a)
-> (Int -> a)
-> (a -> Int)
-> (a -> [a])
-> (a -> a -> [a])
-> (a -> a -> [a])
-> (a -> a -> a -> [a])
-> Enum a
$csucc :: Operator -> Operator
succ :: Operator -> Operator
$cpred :: Operator -> Operator
pred :: Operator -> Operator
$ctoEnum :: Int -> Operator
toEnum :: Int -> Operator
$cfromEnum :: Operator -> Int
fromEnum :: Operator -> Int
$cenumFrom :: Operator -> [Operator]
enumFrom :: Operator -> [Operator]
$cenumFromThen :: Operator -> Operator -> [Operator]
enumFromThen :: Operator -> Operator -> [Operator]
$cenumFromTo :: Operator -> Operator -> [Operator]
enumFromTo :: Operator -> Operator -> [Operator]
$cenumFromThenTo :: Operator -> Operator -> Operator -> [Operator]
enumFromThenTo :: Operator -> Operator -> Operator -> [Operator]
Enum, Operator
Operator -> Operator -> Bounded Operator
forall a. a -> a -> Bounded a
$cminBound :: Operator
minBound :: Operator
$cmaxBound :: Operator
maxBound :: Operator
Bounded, Int -> Operator -> ShowS
[Operator] -> ShowS
Operator -> String
(Int -> Operator -> ShowS)
-> (Operator -> String) -> ([Operator] -> ShowS) -> Show Operator
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Operator -> ShowS
showsPrec :: Int -> Operator -> ShowS
$cshow :: Operator -> String
show :: Operator -> String
$cshowList :: [Operator] -> ShowS
showList :: [Operator] -> ShowS
Show)
data Element = Operator Operator | Operand Integer deriving (Element -> Element -> Bool
(Element -> Element -> Bool)
-> (Element -> Element -> Bool) -> Eq Element
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
$c== :: Element -> Element -> Bool
== :: Element -> Element -> Bool
$c/= :: Element -> Element -> Bool
/= :: Element -> Element -> Bool
Eq, Int -> Element -> ShowS
[Element] -> ShowS
Element -> String
(Int -> Element -> ShowS)
-> (Element -> String) -> ([Element] -> ShowS) -> Show Element
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
$cshowsPrec :: Int -> Element -> ShowS
showsPrec :: Int -> Element -> ShowS
$cshow :: Element -> String
show :: Element -> String
$cshowList :: [Element] -> ShowS
showList :: [Element] -> ShowS
Show)
parsePostfix :: String -> [Element]
parsePostfix :: String -> [Element]
parsePostfix String
expr = (String -> Element) -> [String] -> [Element]
forall a b. (a -> b) -> [a] -> [b]
map String -> Element
parseToken ([String] -> [Element]) -> [String] -> [Element]
forall a b. (a -> b) -> a -> b
$ String -> [String]
words String
expr
parseToken :: String -> Element
parseToken :: String -> Element
parseToken String
x
| (Char -> Bool) -> String -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all Char -> Bool
isDigit String
x = Integer -> Element
Operand (String -> Integer
forall a. Read a => String -> a
read String
x)
| String
x String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
"negate" = Operator -> Element
Operator Operator
Negate
| String
x String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
"+" = Operator -> Element
Operator Operator
Add
| String
x String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
"-" = Operator -> Element
Operator Operator
Subtract
| String
x String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
"*" = Operator -> Element
Operator Operator
Multiply
| String
x String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
"/" = Operator -> Element
Operator Operator
Divide
| String
x String -> String -> Bool
forall a. Eq a => a -> a -> Bool
== String
"%" = Operator -> Element
Operator Operator
Modulo
| Bool
otherwise = Element
forall a. HasCallStack => a
undefined