为 GADT 定义您自己的 Typeable 实例

发布于 2024-11-26 13:55:05 字数 341 浏览 1 评论 0原文

有人可以给我指出一组在 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

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

Can someone point me at a good set of examples for defining Typeable or Typeable1 instances for GADTs in Haskell.

Or, can someone just show my how to define Typeable (manually) for the following 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

Alternately a pointer to the paper that introduced the idea would also be helpful.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

最单纯的乌龟 2024-12-03 13:55:05

看起来该网站现在已经消失了,但是回溯机仍然有链接到所有原始论文的网站: 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 pragma 实际上很重要,因为 mkTyCon 在幕后做了不安全的事情。这就是为什么如果可能的话最好让 GHC 手动派生实例。

我的理解是,在 GHC 的未来版本中将要更改的部分是,您应该使用不同的函数 mkTyCon3,它将包名称、模块名称和类型名称作为单独的参数。这是一个明显的改进,即使使支持多个版本的 GHC 变得更加困难。请参阅:对 Data.Typeable 的更改

以上所有内容确实很旧。

来自 GHC 文档:

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

您永远不需要甚至被允许使用任何现代版本的 GHC 手动编写 Typeable 实例。事实上,您甚至不需要告诉 GHC 来导出它们 - 它会自动执行此操作。

Looks like the website is gone now, but the wayback machine still has the site that links to all the original papers: http://web.archive.org/web/20080622204226/http://www.cs.vu.nl/boilerplate/

In any case, Typeable is almost completely mechanical. You can just derive it, even for GADTs, via the DeriveDataTypeable extension. At least when the kind is * -> *, as in your example.

I can also give an example of manually providing a Typeable1 instance, but it will be deprecated in the next version of GHC. The interface used for creating instances by hand is changing.

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

instance Typeable1 V where
    typeOf1 _ = mkTyConApp vTyCon []

The NOINLINE pragma is actually important, since mkTyCon does unsafe stuff under the hood. This is why it's best to just let GHC derive the instance manually, if possible.

My understanding is the part that will be changing in future versions of GHC is that you should use a different function, mkTyCon3, which takes the package name, module name, and type name as separate arguments. That's a clear improvement, even if makes supporting multiple version of GHC tougher. See: Changes to Data.Typeable.

All of the above is really old.

From the GHC docs:

Also since GHC 7.8.1, handwritten (ie. not derived) instances of Typeable are forbidden, and will result in an error.

You should never need, or even be allowed, to write a Typeable instance by hand with any modern version of GHC. In fact, you don't even need to tell GHC to derive them - it will do that automatically.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文