Home > Back-end >  How to declare a class for a calculator?
How to declare a class for a calculator?

Time:12-15

I am trying to build my own calculator in Haskell with class declaration.

Firstly, I was trying to implement the addition, but here I got the error:

Couldn't match expected type 'Exp -> Double' with actual type 'Exp'

data Exp = Number Double | Add Exp Exp 


class Calc a where
 calculate :: a -> a -> Double

instance Calc Exp where
 calculate (Add a b) = a   b

What do I have to change?

CodePudding user response:

You don't really need, nor would I recommend, a class here. Just define an ordinary function that handles each of the data constructors separately. (Use a class only if you expect to have multiple types that can be used with calculate.)

In either case, calculate takes a single argument, as your type represents an entire expression, operands and operator together.

calculate :: Exp -> Double
calculate (Number n) = ...
calculate (Add a b) = ...

Keep in mind that a and b are values of type Exp, not numbers (i.e., types with a Num instance) that you can add directly. (This suggests you need to recursively calculate the value of a and b before you can actually perform addition.)

Some test cases for you to consider:

n1 = Number 2.0
n2 = Add (Number 3.0) (4.0))
n3 = Add n1 n2

map calculate [n1, n2, n3] == [2.0, 7.0, 9.0]

CodePudding user response:

As suggested by chepner, your calculate function need only take a single argument. You also need to account for the possibility that each Exp value maybe be a Number and handle that in the function.

Since a and b are Exp values and not Num instances, you will need to apple calculate to them.

data Exp = Number Double | Add Exp Exp 

class Calc a where
 calculate :: a -> Double

instance Calc Exp where
 calculate (Number n) = n
 calculate (Add a b) = a'   b'
  where a' = ...
  where b' = ...

But you might consider making Exp an instance of Num. The below is incomplete as it doesn't account for actual expressions except for , but it might hint at what's possible.

instance Num Exp where
 ( ) (Number n1) (Number n2) = Number (n1   n2)
 ( ) (Add a b) c@(Number _) = a   b   c
 ( ) a@(Number _) (Add b c) = a   b   c
 ( ) (Add a b) (Add c d) = a   b   c   d
 (*) (Number n1) (Number n2) = Number (n1 * n2)
 abs (Number n) = Number (abs n)
 negate (Number n) = Number (negate n)
 signum (Number n) = Number (signum n)
 fromInteger n = Number (fromIntegral n)
ghci> case Add (Number 5) (Number 6)   Number 7 of { Number n -> n }
18.0
  • Related