Предположим, у меня есть следующий код:
{-# LANGUAGE GADTs, DeriveDataTypeable, StandaloneDeriving #-}
import Data.Typeable
class Eq t => OnlyEq t
class (Eq t, Typeable t) => BothEqAndTypeable t
data Wrapper a where
Wrap :: BothEqAndTypeable a => a -> Wrapper a
deriving instance Eq (Wrapper a)
deriving instance Typeable1 Wrapper
Затем работает следующее объявление экземпляра без ограничения на t
:
instance OnlyEq (Wrapper t)
и делает то, что я от него ожидаю.
Но следующее объявление экземпляра не работает:
instance BothEqAndTypeable (Wrapper t)
поскольку GHC - я использую 7.6.1 - жалуется, что:
No instance for (Typeable t)
arising from the superclasses of an instance declaration
Possible fix:
add (Typeable t) to the context of the instance declaration
In the instance declaration for `BothEqAndTypeable (Wrapper t)'
Конечно, добавление Typeable t
в контекст работает. Но так же добавляется следующий экземпляр:
instance Typeable (Wrapper t) where
typeOf (Wrap x) = typeOf1 (Wrap x) `mkAppTy` typeOf x
Есть ли способ заставить GHC написать за меня этот последний экземпляр? Если да, то как? Если нет, то почему?
Я надеялся, что GHC сможет извлечь ограничение Typeable
из контекста конструктора Wrap
, как это было с ограничением Eq
. Я думаю, что мои проблемы сводятся к тому, что GHC явно запрещает писать deriving instance Typeable (Wrapper t)
, а стандартный (Typeable1 s, Typeable a) => Typeable (s a)
экземпляр не может «заглянуть внутрь» s a
, чтобы найти Typeable a
словарь.