diff options
Diffstat (limited to 'RealCalc.hs')
| -rw-r--r-- | RealCalc.hs | 50 |
1 files changed, 50 insertions, 0 deletions
diff --git a/RealCalc.hs b/RealCalc.hs new file mode 100644 index 0000000..bf7b3d5 --- /dev/null +++ b/RealCalc.hs @@ -0,0 +1,50 @@ +{-# LANGUAGE RankNTypes #-} + +module RealCalc (calculate) where + +import qualified Expr + +data Result = RInt Integer | RFloat Double + +instance Show Result where + show (RInt i) = show i + show (RFloat d) = show d + +rToDouble :: Result -> Double +rToDouble (RInt i) = fromIntegral i +rToDouble (RFloat d) = d + +genericCombine :: (forall a. Num a => a -> a -> a) -> Result + -> Result -> Result +genericCombine f i j = + case (i, j) of + (RInt a, RInt b) -> RInt (f a b) + _ -> RFloat (f (rToDouble i) (rToDouble j)) + +genericInner :: (forall a. Num a => a -> a) -> Result -> Result +genericInner f (RInt i) = RInt (f i) +genericInner f (RFloat d) = RFloat (f d) + +simplify :: Expr.Expr -> Result +simplify (Expr.Plus e1 e2) = + genericCombine (+) (simplify e1) (simplify e2) +simplify (Expr.Negate e) = genericInner negate (simplify e) +simplify (Expr.Minus e1 e2) = + genericCombine (-) (simplify e1) (simplify e2) +simplify (Expr.Times e1 e2) = + genericCombine (*) (simplify e1) (simplify e2) +simplify (Expr.Div e1 e2) = + RFloat (rToDouble (simplify e1) / rToDouble (simplify e2)) +simplify (Expr.EInt i) = RInt i +simplify (Expr.EFloat d) = RFloat d +simplify Expr.E = RFloat (exp 1) +simplify Expr.Pi = RFloat pi +simplify (Expr.Log e) = RFloat . log . rToDouble $ simplify e +simplify (Expr.Sin e) = RFloat . sin . rToDouble $ simplify e +simplify (Expr.Cos e) = RFloat . cos . rToDouble $ simplify e +simplify (Expr.Sqrt e) = RFloat . sqrt . rToDouble $ simplify e + +calculate :: String -> Maybe String +calculate s = case Expr.parseE s of + Left _ -> Nothing + Right e -> Just . show $ simplify e |
