Haskell 为GADT定义自己的可类型化实例
有人能给我举一组很好的例子来定义Haskell中GADT的Typeable或Typeable1实例吗 或者,有人可以告诉我如何(手动)为下面的GADT定义TypeableHaskell 为GADT定义自己的可类型化实例,haskell,type-conversion,ghc,gadt,Haskell,Type Conversion,Ghc,Gadt,有人能给我举一组很好的例子来定义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 -&
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
或者,指向介绍该想法的论文的指针也会有所帮助。看起来该网站现在已经不存在了,但wayback机器仍然有链接到所有原始论文的网站: 无论如何,打字几乎完全是机械的。您可以通过DeriveDataTypeTable扩展派生它,即使对于GADT也是如此。至少当种类为
*->*
时,如您的示例所示
我还可以给出一个手动提供TypeTable1实例的示例,但在下一版本的GHC中,它将被弃用。用于手动创建实例的界面正在更改
{-# NOINLINE vTyCon #-}
vTyCon :: TyCon
vTyCon = mkTyCon "ModuleName.V"
instance Typeable1 V where
typeOf1 _ = mkTyConApp vTyCon []
由于mkTyCon在引擎盖下做不安全的事情,因此,NOINLINE
pragma实际上很重要。这就是为什么如果可能,最好让GHC手动派生实例
我的理解是,在GHC的未来版本中,将要改变的部分是,您应该使用不同的函数,mkTyCon3
,它将包名、模块名和类型名作为单独的参数。这是一个明显的改进,即使这使得支持多个版本的GHC变得更加困难。请参阅:
所有这些都是非常古老的。
从GHC文件:
此外,自GHC 7.8.1以来,禁止手写(即非派生)可键入实例,并将导致错误
您不应该需要,甚至不应该被允许,用任何现代版本的GHC手工编写一个可键入的实例。事实上,你甚至不需要告诉GHC去推导它们——它会自动地这样做