I'm writing a calculator to add and subtract numbers. I have two abstractions here, an Expr, which is modeled as a tree, and a typeclass Operand, which comprise the left and right nodes of the tree. Operands have a function combine that apply a function to the left and right nodes:
module Data.Calculator where
class Operand a where
combine :: a -> a
data Operator = Plus | Minus
data Expr = Node Operator Operand Operand | Value Integer
instance Operand Expr where
combine (Node op left right) =
case op of
Plus -> (combine left) + (combine right)
Minus -> (combine left) - (combine right)
combine (Value a) = (Value a)
instance Num Expr where
(+) (Value left) (Value right) = Value (left + right)
(*) (Value left) (Value right) = Value (left * right)
abs (Value a) = Value (abs a)
fromInteger i = Value i
negate (Value a) = Value (negate a)
When I try to compile this, I get the error
calculator/src/Data/Calculator.hs:7:35: error:
• Expecting one more argument to ‘Operand’
Expected a type, but ‘Operand’ has kind ‘* -> Constraint’
• In the type ‘Operand’
In the definition of data constructor ‘Node’
In the data declaration for ‘Expr’
|
| data Expr = Node Operator Operand Operand | Value Integer
What does this mean? I'm aware that this problem can be solved without defining Operand as a typeclass, but I'd like to use the Operand typeclass, since that is a subject I'm learning about now. What am I doing wrong?