У меня есть GADT, который очень похож на это:
data In a where
M :: MVar a -> In a
T :: TVar a -> In a
F :: (a -> b) -> In a -> In b
Он охватывает различные входные примитивы, но последний конструктор также допускает экземпляр Functor:
instance Functor In where
fmap f (F g v) = F (f . g) v
fmap f x = F f x
Точкаэтот тип, BTW, должен поддерживать:
read :: In a -> IO a
read (M v) = takeMVar v
read (T v) = atomically (readTVar v)
read (F f v) = f <$> read v
Что я хочу сделать, это определить очевидный экземпляр Eq для этого типа, что-то вроде:
instance Eq (In a) where
(M x) == (M y) = x == y
(T x) == (T y) = x == y
(F _ x) == (F _ y) = x == y
_ == _ = False
проблема - это третий случай, который терпит неудачу, потому что x и y не обязательно имеют один и тот же тип в этой точке.Я это понимаю.В моем собственном коде я могу обойтись долго, но такое ощущение, что должен быть способ определить Eq напрямую.На мой взгляд, решение - это что-то вроде «продолжайте детализировать F-конструкторы, пока не нажмете M или T, тогда, если они одного и того же конструктора (т.е. оба M или оба T) и одного типа, сделайте сравнение на равенство», ноЯ не уверен, как я мог написать это.