blob: bf7b3d589d81d30963cc516369f8b033c0041d82 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
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
|