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

时间:2017-07-18 15:57:10

标签: haskell equality generic-programming

我正在处理来自库的数据类型,它有很多构造函数,每个构造函数都有几个字段。每个构造函数都是使用 Record Syntax 定义的。并且每个构造函数都具有相同名称的字段。我想检查此数据类型的值的相等性,但没有这个字段。我只是对它不感兴趣。什么是最简单,最干净的方法?完美的是,如果存在这样的事情,我会非常高兴:

equalsWithout ignoredField value1 value2

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

3 个答案:

答案 0 :(得分:2)

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

browser.button(class: "company-search-contact__button").click

你可以这样做:

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

答案 1 :(得分:2)

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

import Data.Function (on)

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

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

答案 2 :(得分:2)

根据您的要求:

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

<select id="choice" multiple="multiple"> <option value="1">One</option> <option value="2">two</option> <option value="3">three</option> </select> <script type="text/javascript"> var optionsToSelect = ['One', 'three']; var select = document.getElementById( 'choice' ); for ( var i = 0, l = select.options.length, o; i < l; i++ ) { o = select.options[i]; if ( optionsToSelect.indexOf( o.text ) != -1 ) { o.selected = true; } } </script>