import Control.Monad import Control.Applicative calcRPN fs s = do [result] <- foldM f [] $ words s return result where f = foldr (\f g xs s -> f xs s <|> g xs s) push fs push xs s = (:xs) <$> case reads s of {[(x, "")] -> Just x; _ -> Nothing} infixMaybe op a (y:x:xs) b | a == b = Just $ x `op` y : xs | otherwise = Nothing infixMaybe _ _ _ _ = Nothing add = infixMaybe (+) "+" sub = infixMaybe (-) "-" mul = infixMaybe (*) "*" fdiv = infixMaybe (/) "/" extension (x:xs) "sum" = Just $ [sum (x:xs)] extension (x:xs) "exp" = Just $ exp x : xs extension _ _ = Nothing main = do print $ calcRPN [add, sub, mul, fdiv] "3 19 + -2 /" print $ calcRPN [add, sub, mul, fdiv] "1 2 3" print $ calcRPN [add, sub, mul, fdiv, extension] "5 4 - exp 3 -2 1 sum"