Reputation: 323
I have the following data structures defined:
data Operator = Plus | Times | Minus deriving (Eq,Show)
data Variable = A | B | C deriving (Eq,Show)
newtype Const = D Numeral deriving (Eq,Show)
data CVO = Const | Variable | Operator deriving (Eq,Show)
type Expr = [CVO]
I have defined the following function:
eval2 :: Expr -> Integer
eval2 x = helper x
I would like to check if an element of the CVO list (Expr) is either an instance of Const, Variable or Operator (this works) and I would like to implement varying code for the specific type of the instance (e.g. Plus, Times, Minus for Operator).
helper :: Expr -> Integer
helper [] = 2
helper (x:xs)
| x == Operator && x == Plus = 1
I cannot compare x to Plus, because it expects x to be of type CVO.
Couldn't match expected type ‘CVO’ with actual type ‘Operator’
Is it somehow possible to cast x to be an instance of Operator in order to do the comparison?
Upvotes: 0
Views: 85
Reputation: 44644
A value can't have two different types at the same time. If x
is a CVO
you can't use ==
to compare it to Plus
which is an Operator
.
At the moment the type CVO
consists of three constant values called Const
, Variable
and Operator
. I'm guessing you actually wanted it to contain values of the type Const
, Variable
or Operator
. You do that by declaring arguments to the constructors.
data CVO = Const Const -- a constructor whose name is Const and contains a value of type Const
| Var Variable -- a constructor named Var containing a Variable
| Op Operator -- a constructor named Op containing an Operator
A given value of type CVO
must have been built from one of those three constructors, containing a value of the correct type. You can test which constructor was used to create the CVO
, and simultaneously unpack the value, using pattern matching. Something like this:
helper :: Expr -> Integer
helper [] = 0
helper (Op o:xs) -- because we matched Op, we know o :: Operator
| o == Plus = 1
| otherwise = 2
helper _ = 3
Upvotes: 2