Hello, I’m a newbie here, so this topic means to be my first activity with Haskell community. I’m trying to make a very simple calculator parser using Parsec. Since it reads and processes strings by drawing out some integers, this parser empowers addition, multiplication, subtraction, division, negation and factorial. There are some code lines I added into source file in prior to respective function definitions:
type Parser a = Parsec String () a
digit :: Parser Char
digit = oneOf ['0'..'9']
number :: Parser Integer
number = read <$> many1 digit
applyMany :: a -> [a -> a] -> a
applyMany x [] = x
applyMany x (h:t) = applyMany (h x) t
div_ :: Parser (Integer -> Integer -> Integer)
div_= do
char '/'
return div
star :: Parser (Integer -> Integer -> Integer)
star = do
char '*'
return (*)
plus :: Parser (Integer -> Integer -> Integer)
plus = do
char '+'
return (+)
minus :: Parser (Integer -> Integer -> Integer)
minus = do
char '-'
return (-)
multiplication :: Parser Integer
multiplication = do
spaces
lhv <- atom
spaces
t <- many tail
return $ applyMany lhv t
where tail =
do
f <- star <|> div_
spaces
rhv <- atom
spaces
return (`f` rhv)
addition :: Parser Integer
addition = do
spaces
lhv <- multiplication
spaces
t <- many tail
return $ applyMany lhv t
where tail =
do
f <- plus <|> minus
spaces
rhv <- multiplication
spaces
return (`f` rhv)
atom :: Parser Integer
atom = number <|> do
char '('
res <- addition
char ')'
return res
-- factorial
fact' :: Parser Integer
fact' = do
spaces
char '!'
rhv <- atom
return $ factorial rhv
factorial :: Integer -> Integer
factorial n
| n == 0 || n == 1 = 1
| otherwise = acc n 1
where
acc 0 a = a
acc b a = acc (b-1) (b * a)
-- negation
neg' :: Parser Integer
neg' = do
spaces
char '~'
rhv <- atom
spaces
return $ negate rhv
As you can see, this parser is compatible only with integer numbers. However, I need to extend its features by floating point operations to have an option to perform those as orderly as in cases of integers. May you give any tip how to manage that considering the code provided?