Haskell - 简单的构造函数比较(?)函数 [英] Haskell - simple constructor comparison (?) function
问题描述
在我的项目中,我创建了一个数据类型,它可以保存几种类型的值之一:
data PhpValue = VoidValue | IntValue整数| BoolValue Bool
现在我想要做的是有一个简单的方法来检查两个值 PhpValue
类型是相同的构造函数(纠正我,如果我混淆这里的术语,但基本上我想检查,如果两者都是,例如, code> IntValue ,而不关心特定的值)。
这是我写的一个函数:
sameConstructor: :PhpValue - > PhpValue - > Bool
sameConstructor VoidValue VoidValue = True
sameConstructor(IntValue _)(IntValue _)= True
sameConstructor(BoolValue _)(BoolValue _)= True
sameConstructor _ _ = False
这是可以的,但我不太喜欢它:如果我添加更多的构造函数 FloatValue Float
)我将不得不重写该函数,并且随着数据定义变大,它将变得更大。
问题:有没有写这样一个函数的方法,以便在添加更多构造函数时它的实现不会改变?
记录:我不想更改 data
定义,其余的Monad中有足够的我的代码,因为它;)
看看 Data.Data
及其 toConstr
函数。这会返回一个可以相互比较的构造函数的表示。
使用扩展名(可以将 { - #LANGUAGE DeriveDataTypeable# - }
位于模块的顶部),您可以自动为您创建 Data
实例:
数据PhpValue = VoidValue | IntValue整数| BoolValue Bool
deriving(Typeable,Data)
您应该可以使用 toConstr
函数可以通过构造函数进行比较。
现在,以下情况将成立:
toConstr(BoolValue True)== toConstr(BoolValue False)
在 Data.Function
的上使用,现在可以重写
sameConstructor
到:
sameConstructor =(==)`on` toConstr
$ c
这与
pre> sameConstructor lr = toConstr l == toConstr r
我认为使用的版本
比较容易阅读。
In my project I have created a data type, that can hold one of a few types of values:
data PhpValue = VoidValue | IntValue Integer | BoolValue Bool
What I wanted to do now, is to have a simple way of checking if two values of the PhpValue
type are of the same constructor (correct me if I'm confused with the terminology here, but basically what I want to check if both are, for example, are IntValue
, without caring about the particular value).
Here is a function I wrote for that:
sameConstructor :: PhpValue -> PhpValue -> Bool
sameConstructor VoidValue VoidValue = True
sameConstructor (IntValue _) (IntValue _) = True
sameConstructor (BoolValue _) (BoolValue _) = True
sameConstructor _ _ = False
This works as it should, but I don't really like it: if I add more constructors (like FloatValue Float
) I am going to have to rewrite the function, and it will get bigger as my data definition gets bigger.
The Question: Is there a way of writing such a function, so that its implementation doesn't change when I add more constructors?
For the record: I don't want to change the data
definition, I have enough Monads in the rest of my code as it is ;)
Take a look at Data.Data
and its toConstr
function. This returns a representation of the constructor which can be compared for equality.
With an extension (you can put {-# LANGUAGE DeriveDataTypeable #-}
at the top of your module), you can have a Data
instance derived for you automatically:
data PhpValue = VoidValue | IntValue Integer | BoolValue Bool
deriving (Typeable, Data)
You should then be able to use the toConstr
function to compare by constructor.
Now the following will be true:
toConstr (BoolValue True) == toConstr (BoolValue False)
Using on
from Data.Function
you can now rewrite sameConstructor
to:
sameConstructor = (==) `on` toConstr
This is the same as
sameConstructor l r = toConstr l == toConstr r
I think the version using on
is easier to read at a glance.
这篇关于Haskell - 简单的构造函数比较(?)函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!