5

有人可以指出一组很好的示例,用于在 Haskell 中为 GADT 定义 Typeable 或 Typeable1 实例。

或者,有人可以向我展示如何为以下 GADT 定义 Typeable(手动)。

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

或者,指向介绍该想法的论文的指针也会有所帮助。

4

1 回答 1

8

看起来网站现在已经消失了,但回路机仍然有链接到所有原始论文的网站:http://web.archive.org/web/20080622204226/http: //www.cs.vu.nl/样板/

无论如何,Typeable 几乎完全是机械的。即使对于 GADT,您也可以通过 DeriveDataTypeable 扩展导出它。至少当 kind 是* -> *,就像你的例子一样。

我也可以举一个手动提供 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 的更改

以上都是真的老了。

来自 GHC 文档:

此外,从 GHC 7.8.1 开始,Typeable 的手写(即非派生)实例被禁止,并且会导致错误。

您永远不需要,甚至不应该被允许Typeable使用任何现代版本的 GHC 手动编写实例。事实上,你甚至不需要告诉 GHC 来推导它们——它会自动完成。

于 2011-07-26T17:11:38.277 回答