Comparing values by their constructors
I have a data type defined like this:
data Token
= Literal Integer
| Operator String
| Separator Char
| Identifier String
If I have a value of type Token
, is there an elegant way to check if its type constructor is e.g. Operator
? Or even more: is there a way to check if two values of type Token
are instances of the same constructor?
I could obviously create functions:
isOperator :: Token -> Bool
isOperator (Operator _) = True
isOperator _ = False
haveSameConstructor :: Token -> Token -> Bool
haveSameConstructor (Literal _) (Literal _) = True
haveSameConstructor (Operator _) (Operator _) = True
haveSameConstructor (Separator _) (Separator _) = True
haveSameConstructor (Identifier _) (Identifier _) = True
haveSameConstructor _ = False
However, this is really verbose, especially if the type has more constructors. Or I could use case ... of
but using it always when I need to compare the constructors seems repetitive to me. Is there some clever solution? E.g. something like a function isKindOf Operator token
.
Thanks to user1984 posting a link to this question I have been able to figure out a solution:
{-# LANGUAGE DeriveDataTypeable #-}
import Data.Data
data Token
= Literal Integer
| Operator String
| Separator Char
| Identifier String deriving (Show, Eq, Typeable)
sameConstructor :: Token -> Token -> Bool
sameConstructor a b = toConstr a == toConstr b
It doesn't let me check if a value is an instance of a particular constructor but at least I can replace it by comparing two values like this sameConstructor token (Operator "")
.