aboutsummaryrefslogtreecommitdiffstats
path: root/RealCalc.hs
diff options
context:
space:
mode:
Diffstat (limited to 'RealCalc.hs')
-rw-r--r--RealCalc.hs50
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