You are confusing two very different topics (if you pasted the error messages this might have surfaced sooner and gotten you better feedback). Lets look at what was provided to you - the Expr data type and the classes.
A Classy Confusion
You were provided with:
data Expr a = Var Char
| Const a
| (Expr a) :+: (Expr a)
| (Expr a) :*: (Expr a)
| (Expr a) :^: (Expr a)
| (Expr a) :/: (Expr a)
deriving (Show, Eq)
Here we can see the constructors are basic arithmetic operations. Stated another way, :+: is a constructor of type Expr a -> Expr a -> Expr a and similarly for the others.
Now you go on to try and define a function, namely :+::
class (Num a) => Expr a where
(:+:) :: a -> a -> a
instance Expr a where
x :+: y = x + y
There are a few problems here.
- You class
Expr is merely named the same as the above type, it has no relation to the data defined above.
- Your method
:+: is not a legal function name. Functions, unlike data constructors, must be valid variables and thus can not start with upper case or colon characters.
- The instance is for all types -
a is a variable and can match any type. So you have yet to say the x and y values are of type Expr a.
I think you were trying to make a class for each operator and make an instance for each constructor (:+:, :*:, etc). This is a broken, or at least overly verbose, solution. The only reason to use classes are if there are multiple type that require instances - you only have the oneExpr` type.
Classless
There is no need for type classes to solve this problem, instead you can evaluate an expression with a traditional function, much like in the deleted answer.
The previously deleted answer appears to be deleted with the notion that and an environment of bindings for each variable is necessary. My reading of the problem is different and I would simply evaluate the expression into a simple string.
evaluate :: Show a => Expr a -> String
evaluate (Var c) = [c]
evaluate (a :+: b) = undefined
evaluate (a :*: b) ... so on and so forth ...
In the above you pattern match your Expr a to determine the operation then, on a case by case basis, evalute the sub-expressions as necessary before combining them in a manner dependent on the constructor (+ with :+: etc).
xandyinx :+: yareExpr as. You’re going to have to actually implement the whole simplification thing, e.g.Const a :+: Const b = Const (a + b)evaluate :: Fractional a => Expr a -> a. (You're going to needFractionalfor division, everything else is inNum.)simp (x :*: (y :/: x')) | x == x' = y; simp ...Simplifying this expression "fully" is fairly non-trivial so I don't know which simplifications exactly you are expected to perform.:+:and:*:. Then it's only polynomials (albethey of multiple variables) that you're dealing with, and polynomials can nicely be transformed to some standard form.