diff options
| author | Raymond Hogenson <rhogenson@posteo.net> | 2018-05-17 09:42:44 -0800 |
|---|---|---|
| committer | Raymond Hogenson <rhogenson@posteo.net> | 2018-05-17 09:43:54 -0800 |
| commit | 78001436a52a4cc9b5e22bca489fb8ed09a72376 (patch) | |
| tree | 0c88a126b1169000d6312d21792b10e8724fab6f /RealCalc.hs | |
| download | hsc-78001436a52a4cc9b5e22bca489fb8ed09a72376.tar.zst | |
Write a calculator
It's pretty nice. It works for what I want. I don't think I have any
complaints about its functionality. I'll add new functions as I need
them. Haskell is actually really easy to program in. I wonder actually
if this would have been easier in Python. I think no.
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 |
