module StackExpr where data Instr = Const Integer | Add | Sub | Mul | Neg | Abs | Sig deriving (Show) newtype Program = P [Instr] deriving (Show) instance Num Program where fromInteger i = P [Const i] P a + P b = P (b ++ a ++ [Add]) P a - P b = P (b ++ a ++ [Sub]) P a * P b = P (b ++ a ++ [Mul]) negate (P a) = P (a ++ [Neg]) abs (P a) = P (a ++ [Abs]) signum (P a) = P (a ++ [Sig]) eval :: Program -> Integer eval (P xs) = go [] xs where go (x:_) [] = x go xs (Const i:ys) = go (i:xs) ys go (a:b:xs) (Add:ys) = go ((a+b):xs) ys go (a:b:xs) (Mul:ys) = go ((a*b):xs) ys go (a:b:xs) (Sub:ys) = go ((a-b):xs) ys go (a:xs) (Neg:ys) = go ((negate a):xs) ys go (a:xs) (Abs:ys) = go ((abs a):xs) ys go (a:xs) (Sig:ys) = go ((signum a):xs) ys