Самый простой способ сравнить значения большого типа данных, игнорируя одно поле или без этого поля

Я работаю с типом данных из библиотеки, которая имеет много конструкторов, и каждый конструктор имеет несколько полей. Каждый конструктор определяется с использованием синтаксиса записи. И каждый конструктор имеет поле с тем же именем. Я хочу проверить равенство значений этого типа данных, но без этого одного поля. Я просто не заинтересован в этом. Какой самый простой и чистый способ сделать? Отлично, я был бы чрезвычайно счастлив, если бы что-то подобное существовало:

equalsWithout ignoredField value1 value2

Самый простой способ, который я могу себе представить, это перевести этот тип данных в [String] с помощью Show и сравните списки результатов. Но я хотел бы избежать этого, потому что это требует написания большого количества стандартного кода, потому что тип данных имеет много конструкторов... Может быть, есть более чистый способ добиться этого.

3 ответа

Решение

По вашему запросу:

Скопируйте значение из одного в другое, а затем сравните:

a { foo = foo b } == b

Если вы не можете выделить элемент, который хотите избежать, то следующим лучшим решением будет проецировать оставшиеся данные в структуру, которая имеет удобную Eq Например, как кортеж:

import Data.Function (on)

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

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

Возможно, лучшим подходом было бы просто разделить это поле по вашему типу. Вместо

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
Другие вопросы по тегам