比较忽略一个字段或没有该字段的大数据类型值的最简单方法

Easiest way to compare values of big data type ignoring one field or without that field

提问人:Shersh 提问时间:7/18/2017 更新时间:7/19/2017 访问量:283

问:

我正在使用库中的数据类型,该库有很多构造函数,每个构造函数都有几个字段。每个构造函数都是使用 Record 语法定义的。每个构造函数都有同名的字段。我想检查此数据类型的值是否相等,但没有这个字段。我只是对它不感兴趣。最简单、最干净的方法是什么?完美地,如果存在这样的东西,我会非常高兴:

equalsWithout ignoredField value1 value2

我能想象到的最简单的方法是将此数据类型转换为使用和比较结果列表。但我想避免这种情况,因为它需要编写大量样板代码,因为数据类型有很多构造函数......也许有更清洁的方法来实现这一目标。[String]Show

Haskell 等式 泛型编程

评论

0赞 willeM_ Van Onsem 7/19/2017
在编译时是已知的吗?还是仅在运行时?ignoredField
4赞 soupi 7/19/2017
将值从一个复制到另一个,然后进行比较:a { foo = foo b } == b
0赞 Shersh 7/19/2017
@WillemVanOnsem在编译时是已知的。ignoredField
0赞 Shersh 7/19/2017
@soupi太棒了!现在我觉得很愚蠢:(应该为这种愚蠢的问题感到羞耻。同时,我真的很喜欢有这样一个简单而优雅的解决方案!如果您发布它,可以接受作为答案。

答:

2赞 NovaDenizen 7/19/2017 #1

也许最好的方法是将该字段从您的类型中拆分出来。而不是

data MyData = C1 IgnoredType T1 T2
            | C2 IgnoredType T2 T3
            | C3 IgnoredType T4

你可以这样做:

data MySimpleData = C1 T1 T2
                  | C2 T2 T3
                  | C3 T4
    deriving Eq

data WithIgnored a = WI IgnoredType a
instance Eq a => Eq (WithIgnored a) where
    WI _ x == WI _ y = x == y
type MyData = WithIgnored MySimpleData

或者不太灵活:

data MyData = MD IgnoredType MySimpleData
instance Eq MyData where
    MD _ x == MD _ y = x == y

评论

0赞 Shersh 7/19/2017
感谢您的回答!不幸的是,我无法拆分该字段。因为我正在使用问题中提到的库中的数据类型,所以这不是我自己:(虽然我同意你的看法,但这样的设计在某种意义上会更好。
2赞 Rein Henrichs 7/19/2017 #2

如果无法拆分出要避免比较的项目,那么下一个最佳解决方案是将其余数据投影到具有方便实例(如元组)的结构中:Eq

import Data.Function (on)

myDataComparables (MyData a b c d) = (b,c,d)

instance Eq MyData where
  (==) = (==) `on` myDataComparables

评论

0赞 Rein Henrichs 7/19/2017
好吧,也许下一个最好的是@soupi的,但这个也相当不错。:)
0赞 Shersh 7/19/2017
我不想写函数,因为数据类型有几十个构造函数。我不能使用元组,因为这些构造函数具有不同类型的字段。虽然我可以转换为我在问题中提到的。是的,我真的很喜欢@soupi的回答:)myDataComparables[String]
0赞 Rein Henrichs 7/19/2017
另一个答案是尘土飞扬。:)
2赞 soupi 7/19/2017 #3

根据您的要求:

将值从一个复制到另一个,然后进行比较:

a { foo = foo b } == b

评论

0赞 Shersh 7/19/2017
再次感谢!另外,我想指出的是,这种方法也扩展到任何数量的领域。