У меня есть 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) и того же типа, выполните сравнение равенства», но я Не знаю, как я мог это написать.