RosettaCodeData/Task/Arithmetic-evaluation/Haskell/arithmetic-evaluation.hs

48 lines
977 B
Haskell
Raw Permalink Normal View History

2017-09-23 10:01:46 +02:00
{-# LANGUAGE FlexibleContexts #-}
2015-11-18 06:14:39 +00:00
import Text.Parsec
import Text.Parsec.Expr
import Text.Parsec.Combinator
import Data.Functor
2016-12-05 22:15:40 +01:00
import Data.Function (on)
2013-04-10 14:58:50 -07:00
2017-09-23 10:01:46 +02:00
data Exp
= Num Int
| Add Exp
Exp
| Sub Exp
Exp
| Mul Exp
Exp
| Div Exp
Exp
2013-04-10 14:58:50 -07:00
2017-09-23 10:01:46 +02:00
expr
:: Stream s m Char
=> ParsecT s u m Exp
2013-04-10 14:58:50 -07:00
expr = buildExpressionParser table factor
2017-09-23 10:01:46 +02:00
where
table =
[ [op "*" Mul AssocLeft, op "/" Div AssocLeft]
, [op "+" Add AssocLeft, op "-" Sub AssocLeft]
]
op s f = Infix (f <$ string s)
factor = (between `on` char) '(' ')' expr <|> (Num . read <$> many1 digit)
2013-04-10 14:58:50 -07:00
2017-09-23 10:01:46 +02:00
eval
:: Integral a
=> Exp -> a
eval (Num x) = fromIntegral x
eval (Add a b) = eval a + eval b
eval (Sub a b) = eval a - eval b
eval (Mul a b) = eval a * eval b
2016-12-05 22:15:40 +01:00
eval (Div a b) = eval a `div` eval b
2013-04-10 14:58:50 -07:00
2017-09-23 10:01:46 +02:00
solution
:: Integral a
=> String -> a
2015-11-18 06:14:39 +00:00
solution = either (const (error "Did not parse")) eval . parse expr ""
2017-09-23 10:01:46 +02:00
main :: IO ()
main = print $ solution "(1+3)*7"