Определение ваших собственных экземпляров Typeable для GADT - PullRequest
3 голосов
/ 26 июля 2011

Может кто-нибудь указать мне хороший набор примеров для определения экземпляров Typeable или Typeable1 для GADT в Haskell.

Или кто-то может просто показать, как определить Typeable (вручную) для следующего GADT.

data V a where
    Unit :: V () 
    Pair :: V a -> V b -> V (a, b) 
    L :: V a -> V (Either a b) 
    R :: V b -> V (Either a b) 
    Fresh :: Int -> V a

Альтернативно указатель на документ, который представил идею, также будет полезен.

1 Ответ

7 голосов
/ 26 июля 2011

Похоже, что веб-сайт больше не существует, но у машины обратного хода все еще есть сайт, который ссылается на все оригинальные документы: http://web.archive.org/web/20080622204226/http://www.cs.vu.nl/boilerplate/

В любом случае, Typeable почти полностью механический. Вы можете просто получить его, даже для GADT, через расширение DeriveDataTypeable. По крайней мере, когда тип * -> *, как в вашем примере.

Я также могу привести пример ручного предоставления экземпляра Typeable1, но он будет устаревшим в следующей версии GHC. Изменяется интерфейс, используемый для создания экземпляров вручную.

{-# NOINLINE vTyCon #-}
vTyCon :: TyCon
vTyCon = mkTyCon "ModuleName.V"

instance Typeable1 V where
    typeOf1 _ = mkTyConApp vTyCon []

Прагма NOINLINE действительно важна, поскольку mkTyCon делает небезопасные вещи под капотом. Вот почему лучше всего позволить GHC получить экземпляр вручную, если это возможно.

Насколько я понимаю, часть, которая будет изменяться в будущих версиях GHC, заключается в том, что вам следует использовать другую функцию mkTyCon3, которая принимает имя пакета, имя модуля и имя типа в качестве отдельных аргументов. Это явное улучшение, даже если усложняет поддержку нескольких версий GHC. См .: Изменения в Data.Typeable .

...