Skip to content

Instantly share code, notes, and snippets.

@kei-q
Created August 14, 2012 15:59
Show Gist options
  • Select an option

  • Save kei-q/3350484 to your computer and use it in GitHub Desktop.

Select an option

Save kei-q/3350484 to your computer and use it in GitHub Desktop.
10.1
import Control.Monad (mplus)
data Token = TInt Int
| Operator (Int -> Int -> Int)
sample :: String
sample = "10 4 3 + 2 * -"
calc :: String -> Int
calc = calc' [] . tokenize
calc' :: [Int] -> [Token] -> Int
calc' [n] [] = n
calc' stack (TInt n : ts) = calc' (n : stack) ts
calc' (a:b:ss) (Operator o : ts) = calc' (o b a : ss) ts
calc' _ _ = error "calc error"
tokenize :: String -> [Token]
tokenize = map token . words
operatorTable :: [(String, Int->Int->Int)]
operatorTable = [("+", (+)), ("-", (-)), ("*", (*))]
token :: String -> Token
token s = case token' s of
Just x -> x
Nothing -> error "parse error"
token' :: String -> Maybe Token
token' s = (Operator `fmap` lookup s operatorTable)
`mplus` (TInt `fmap` readMaybe s)
readMaybe :: (Read a) => String -> Maybe a
readMaybe s = case reads s of
[(x, "")] -> Just x
_ -> Nothing
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment