【问题标题】:`deriving (Data)` vs `deriving (Generic)``派生(数据)`与`派生(通用)`
【发布时间】:2014-09-29 13:05:06
【问题描述】:

这两者在 GHC 中有什么区别。它们的预期用途似乎相似,但 deriving (Data) 已经存在了一段时间,而 deriving (Generic) 最近才被添加到 GHC 中。

deriving (Generic) 基本上是“升级”到deriving (Data) 还是这两个类有不同的目的?

【问题讨论】:

  • 这些只是类型类——您可以查看方法并推断它们的用途。简而言之,Data 提供了遍历数据结构的灵活方法,而Generic 提供了一种将用户定义的结构转换为单个“产品总和”形式的方法;然后由用户定义如何遍历这个产品总和 AST。
  • 您可能对一些论文感兴趣:dreixel.net/research/pdf/gdmh.pdf(Generic 简介)、haskell.org/haskellwiki/Research_papers/Generics(概述中的一些比较,以及在 Data.Data 上废弃你的样板以获取信息)。这些通常都非常易读。

标签: haskell ghc


【解决方案1】:

我几乎犹豫要不要回答这个问题,因为我自己只是勉强理解它,但我确实花了几天时间自己在大约一年前看这个,这是我目前的理解......

这两个类都用于自省......使用它们,您可以访问(Haskell 程序本身的)Haskell 代码分析树。

然而,从哲学上讲,他们这样做的方式不同。

  1. 派生(数据)创建数据对象,这些对象表示可在运行时操作的已解析对象树。

  2. 派生(通用)创建与每个分析树对应的新类型,通常可以在编译时对其进行操作(在运行时完成的工作更少)。

从我有限的使用情况来看,“派生(数据)”使用起来要简单得多,但在运行时当然没有那么流畅(....对我来说这可以忽略不计)。

虽然“派生(通用)”在理论上更快,但编程更棘手,并且涉及创建可以操作类型组(即相关分析树)的类。它还可能促使您使用最先进的 GHC 扩展。

我的意见-“派生(通用)”是做事的“正确”方式,但需要更长的时间才能掌握。

Template Haskell 是访问 Haskell 分析树的另一种方法,尽管它在编译时 100% 工作,并且具有让您创建插入将树数据分析到代码中的工具(即生成代码的代码,如 Lisp 宏)。

再次强调,这一切都是基于几天的研究,所以如果我把这件事弄得太糟糕了,有人让我知道(我自己想巩固我的理解)。

【讨论】:

  • 感谢 cmets。我投了赞成票,但如果有其他见解,我会保留这个问题。
  • 派生Data 创建Data 字典(类型类实例),它提供了在对象树上工作的高阶函数(特别是gfoldl)。此外,恕我直言,GenericData 更易于使用,代码也更简单。
  • @JohnL 我们不要忘记提到样板通用原因中对数据的指数爆炸(例如:使用通用类的遍历与来自 SYB 的 everything 等人的遍历)!
猜你喜欢
  • 1970-01-01
  • 2012-07-17
  • 1970-01-01
  • 2017-01-05
  • 2012-11-25
  • 2012-02-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多