blob: 11eebe41ec57e6aa32630b3cb02a0a57f6d0ee81 (
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
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
|
{-# LANGUAGE RankNTypes #-}
{-
- Copyright 2018 Raymond Hogenson
-
- This file is part of RealCalc.
- RealCalc is free software: you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation, either version 3 of the License, or
- (at your option) any later version.
-
- RealCalc is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with RealCalc. If not, see <http://www.gnu.org/licenses/>.
-}
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
|