I am implementing an Expression solver, but I am having some problems with pattern matching.
I have the following code
data Expression a where
Const ∷ Int → Expression Int
Add ∷ Expression Int → Expression Int → Expression Int
Sub ∷ Expression Int → Expression Int → Expression Int
eval ∷ Expression a → a
eval (Const a) = a
eval (Add exp1 exp2) = (val1 + val2)
where
val1 = eval exp1
val2 = eval exp2
eval (Sub exp1 exp2) = (val1 - val2)
where
val1 = eval exp1
val2 = eval exp2
But since eval Add and eval Sub are very similar and I could want another operations I though of doing a more generic implementation, but I am having some problems.
I though of doing like
data Op = Add | Sub
data Expression a where
Const ∷ Int → Expression Int
Op ∷ Expression Int → Expression Int → Expression Int
eval (Op exp1 exp2) = case Op of
Add → (val1 + val2)
Sub → (val1 - val2)
where
val1 = eval exp1
val2 = eval exp2
But it doesn’t work. Is it possible to do something like this?
Thanks in advance
This does not work because you are defining
Opas both a data constructorand a type. The type
Ophas two constructorsAddandSub, but theExpressiontype has anOpconstructor. This code is confusing the two.The case statement of your
evalfunction attempts to match of the valueOp, butOpis a constructor that takes two arguments in this context,so you can’t pattern match on it. I suspect you are going for something like
this
You will have to include a field in the
Opconstructor that denotes whatoperation is to be performed. Since you have to match on the that operation
anyway, it would probably be nicer to stick with the original definition of
Expression.Another possibility that is simpler and easier to extend might be something like
the following
where an
Opwraps the actual function up with it. You would not be able todo nice things like print out the expression and know what function it
corresponds to though.