通过构造函数比较值
Comparing values by their constructors
我有一个这样定义的数据类型:
data Token
= Literal Integer
| Operator String
| Separator Char
| Identifier String
如果我有一个 Token
类型的值,有没有一种优雅的方法来检查它的类型构造函数是否是例如Operator
?甚至更多:有没有办法检查 Token
类型的两个值是否是同一构造函数的实例?
我显然可以创建函数:
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
但是,这确实很冗长,尤其是当该类型具有更多构造函数时。或者我可以使用 case ... of
但是当我需要比较构造函数时总是使用它对我来说似乎是重复的。有什么聪明的解决办法吗?例如。类似于函数 isKindOf Operator token
.
感谢 user1984 posting a link to this question 我找到了解决方案:
{-# 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
它不允许我检查某个值是否是特定构造函数的实例,但至少我可以通过比较两个值来替换它 sameConstructor token (Operator "")
。
我有一个这样定义的数据类型:
data Token
= Literal Integer
| Operator String
| Separator Char
| Identifier String
如果我有一个 Token
类型的值,有没有一种优雅的方法来检查它的类型构造函数是否是例如Operator
?甚至更多:有没有办法检查 Token
类型的两个值是否是同一构造函数的实例?
我显然可以创建函数:
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
但是,这确实很冗长,尤其是当该类型具有更多构造函数时。或者我可以使用 case ... of
但是当我需要比较构造函数时总是使用它对我来说似乎是重复的。有什么聪明的解决办法吗?例如。类似于函数 isKindOf Operator token
.
感谢 user1984 posting a link to this question 我找到了解决方案:
{-# 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
它不允许我检查某个值是否是特定构造函数的实例,但至少我可以通过比较两个值来替换它 sameConstructor token (Operator "")
。