1

This is a calculator that only sums numbers:

module Data.Calculator where

data Expr = Plus Expr Expr | Value Int

evaluate :: Expr -> Int
evaluate (Value a) = a
evaluate (Plus (Value a) (Value b)) = a + b
evaluate (Plus (Plus left right) (Value b)) = (evaluate left) + (evaluate right) + b
evaluate (Plus (Value a) (Plus left right)) = a + (evaluate left) + (evaluate right)
evaluate (Plus a@(Plus left right) b@(Plus left' right')) = (evaluate a) + (evaluate b)

The evaluate function seems way to verbose. Ideally I'd like to define a typeclass both operators and then define Plus as an instance of an operator, something like this:

class BinaryOp a where
    apply :: a -> a -> Expr

instance BinaryOp Plus where
    apply x y = x + y

But this obviously does not work because the type a that BinaryOp is defined with is an operator and not an operand.

How do I do this?

1 Answer 1

4

Your evaluate function can be just

evaluate :: Expr -> Int
evaluate (Value x) = x
evaluate (Plus x y) = evaluate x + evaluate y

as all cases are accounted for.

For per the typeclass, you cannot create an instance for Plus since that's a constructor and you need to specify instances for types (in this case Expr is the type, while Plus and Value are the constructors). If you wanted a typeclass that takes two elements of a certain type and produces an Int, you could write something like this:

data Expr = Plus Expr Expr | Value Int

class BinaryOp a where
    apply :: a -> a -> Int

instance BinaryOp Expr where
    apply x y = evaluate $ Plus x y
Sign up to request clarification or add additional context in comments.

3 Comments

If evaluate has type Expr -> Int, then I think apply should be \x y -> evaluate (Plus x y) rather than just evaluate.
I'd argue that using a typeclass is a bad idea here. A typeclass may be useful when there are many types involved -- here there's only one.
@AlexisKing Yes you're absolutely right thanks for catching that!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.