Haskell - 简单的构造函数比较(?)函数 [英] Haskell - simple constructor comparison (?) function

查看:63
本文介绍了Haskell - 简单的构造函数比较(?)函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的项目中,我创建了一个数据类型,它可以保存几种类型的值之一:

  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 



这与
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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆