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