Определение экземпляра Eq для Haskell GADT

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

15
задан Neil Brown 17 May 2011 в 09:50
поделиться