fork download
  1. import Control.Monad
  2. import Control.Applicative
  3.  
  4. calcRPN fs s = do
  5. [result] <- foldM f [] $ words s
  6. return result
  7. where
  8. f = foldr (\f g xs s -> f xs s <|> g xs s) push fs
  9. push xs s = (:xs) <$> case reads s of {[(x, "")] -> Just x; _ -> Nothing}
  10.  
  11.  
  12. infixMaybe op a (y:x:xs) b | a == b = Just $ x `op` y : xs
  13. | otherwise = Nothing
  14. infixMaybe _ _ _ _ = Nothing
  15.  
  16. add = infixMaybe (+) "+"
  17. sub = infixMaybe (-) "-"
  18. mul = infixMaybe (*) "*"
  19. fdiv = infixMaybe (/) "/"
  20.  
  21. extension (x:xs) "sum" = Just $ [sum (x:xs)]
  22. extension (x:xs) "exp" = Just $ exp x : xs
  23. extension _ _ = Nothing
  24.  
  25. main = do
  26. print $ calcRPN [add, sub, mul, fdiv] "3 19 + -2 /"
  27. print $ calcRPN [add, sub, mul, fdiv] "1 2 3"
  28. print $ calcRPN [add, sub, mul, fdiv, extension] "5 4 - exp 3 -2 1 sum"
Success #stdin #stdout 0.02s 3728KB
stdin
Standard input is empty
stdout
Just (-11.0)
Nothing
Just 4.718281828459045