Return Styles: Pseud0ch, Terminal, Valhalla, NES, Geocities, Blue Moon.

Pages: 1-

Calculator

Name: smott 2005-07-09 11:44

{-
Man, this board is slow. Here, have a calculator.
very minimalist, but i think it can do most things.
of course it's horribly verbose, but writing a real
parser = pain. the code is very simple and elegant
imo
-}

module Main
    where

import System.Environment (getArgs)
import Control.Monad        (liftM)

data Exp = Add Exp Exp | Mul Exp Exp
         | Sin Exp     | Neg Exp
         | Num Float   | Inv Exp
    deriving (Show, Read, Eq)

eval :: Exp -> Float
eval (Add e1 e2) = eval e1  +   eval e2
eval (Mul e1 e2) = eval e1  *   eval e2
eval (Sin    e1) = sin      $   eval e1
eval (Neg    e1) = negate   $   eval e1
eval (Inv    e1) = 1        /   eval e1
eval (Num     n) = n

main :: IO ()
main = liftM unwords getArgs
       >>= print . eval . read


{-
# works like this:
$ ghc --make qcalc.hs -o qcalc
Chasing modules from: qcalc.hs
Compiling Main             ( qcalc.hs, qcalc.o )
Linking ...
$ ./qcalc "Sin (Add (Inv (Num 3.0)) (Neg (Num 2.0)))"
-0.99540794
-}

Name: Anonymous 2005-07-09 12:08

This is my calculator

print eval("@ARGV")

AM I RITE?

Name: Anonymous 2005-07-10 6:09

I just start up clisp and start typing in expressions.

Name: Anonymous 2005-07-10 6:56 (sage)

Ew prefix notation D:

Name: Anonymous 2005-07-10 14:56

here is some post-fix goodness
complete with parsing abilities :o

data Exp = Add | Min | Mul | Div | Sin | Num Double

parse = map f where
    f "+" = Add
    f "-" = Min
    f "*" = Mul
    f "/" = Div
    f "sin" = Sin
    f x = Num (read x)

eval (Num n:xs) ys = eval xs (n:ys)
eval (Sin:xs) (n:ys) = eval xs (sin n:ys)
eval (Add:xs) (m:n:ys) = eval xs (m+n:ys)
eval (Min:xs) (m:n:ys) = eval xs (m-n:ys)
eval (Mul:xs) (m:n:ys) = eval xs (m*n:ys)
eval (Div:xs) (m:n:ys) = eval xs (m/n:ys)
eval _ ys = ys

calc = flip eval [] . parse . words

Name: Anonymous 2005-07-10 15:03

evalparse ("+"  :xs) (m:n:ys) = evalparse xs (m+n:ys)
evalparse ("-"  :xs) (m:n:ys) = evalparse xs (m-n:ys)
evalparse ("*"  :xs) (m:n:ys) = evalparse xs (m*n:ys)
evalparse ("/"  :xs) (m:n:ys) = evalparse xs (m/n:ys)
evalparse ("sin":xs) (  n:ys) = evalparse xs (sin n:ys)
evalparse (x:xs) ys = evalparse xs ((read x :: Double):ys)
evalparse _ ys = ys

which is better, this or my previous one?

Name: Anonymous 2005-07-10 15:06

PS. calc = flip evalparse [] . words

Name: Anonymous 2005-07-10 15:07

needs more "echo $[MATH_EXPRESSION_GOES_HERE]" amirite?

Name: Anonymous 2005-07-10 15:24

eval made smaller

eval = foldl f [] where
  f ys (Num n) = n:ys
  f (n:ys)   Sin = sin n:ys
  f (m:n:ys) Add = m+n:ys
  f (m:n:ys) Min = m-n:ys
  f (m:n:ys) Mul = m*n:ys
  f (m:n:ys) Div = m/n:ys
  f ys _ = ys

Name: Anonymous 2005-07-10 15:25

here, calc = eval . parse . words

Name: Anonymous 2005-07-10 15:30

i'm done

evalparse = foldl f [] where
  f (m:n:ys) "+" = m+n:ys
  f (m:n:ys) "-" = m-n:ys
  f (m:n:ys) "*" = m*n:ys
  f (m:n:ys) "/" = m/n:ys
  f (n:ys) "sin" = sin n:ys
  f ys x = (read x :: Double):ys

calc = evalparse . words

Name: Anonymous 2005-07-10 17:25

orz...i fucked up the evaluation order

Name: Anonymous 2005-07-10 19:14

Prefix/postfix are for sick people

You can do all that crap in a Perl script with just one line (Windows) or two lines (*ix).

Name: Anonymous 2005-07-10 21:14

I must be sick then, because I love RPN.

Until you've used a stack-based calculator that uses RPN, like some of HP's older calculators, you just can't appreciate its wonders. Infix notation frankly stinks for doing anything other than sitting in a book.

Name: Anonymous 2005-07-11 4:38

>>14

nice, although mine now has variables that can store arbitrary expressions. good luck doing that in rpn!

Name: Anonymous 2005-07-11 5:52

>>15
Well you could do that with RPN. Something like this:

3 6 + STORE a

a 45 /   =====>   0.2

Name: Anonymous 2005-07-11 5:58

Storing functions:

[3 +] STORE f

34 f  ====>  37

Name: Anonymous 2005-07-11 8:35

MORE LIKE f+=3 AM I RITE

Name: Anonymous 2005-07-11 11:05

>>15
- My poor old calc can do that too. ;_;
- RPN doesn't prevent that. Hell, that's almost the basis of Forth. Lisp does it too, albeit prefix instead of postfix.

Name: Anonymous 2009-08-03 8:03

20 GET

Name: Anonymous 2009-08-03 8:07

>>18
LOL U R RITE

Name: Anonymous 2011-01-31 21:37

<-- check em dubz

Name: tray 2012-03-16 16:14

flagStuff|=1;

Name: Anonymous 2013-06-30 2:02

CALCULATOR calculating

Don't change these.
Name: Email:
Entire Thread Thread List