在Haskell中使用`deriving`引发了什么?

时间:2014-11-01 21:20:54

标签: haskell

我刚开始学习Haskell。我已经看过许多介绍类型基础知识的介绍示例,但它们通常在类型下面有一个deriving语句。以下是Chapter 3 of RealWorldHaskell的示例:

data Cartesian2D = Cartesian2D Double Double
                   deriving (Eq, Show)

data Polar2D = Polar2D Double Double
               deriving (Eq, Show)

他们解释了Chapter 6中的某种推导,它可以帮助您了解它的使用方式。

到目前为止,据我所知,deriving (Show)是必要的,告诉Haskell如何将您的类型转换为字符串。这在实际层面上是有道理的。我来自JavaScript领域,所以对我来说,你很容易想象这将实现如下:

Polar2D.prototype.toString = function(){
  return '[Polar2D]';
};

在Haskell中,他们举例说明了如何为Show类型实现自己的Color,而不是使用deriving

data Color = Red | Green | Blue
instance Show Color where
  Red = "red"
  Green = "green"
  Blue = "blue"

这意味着当你进入ghci repl时,你可以这样做:

> show Red
"red"

但这并不能解释deriving实际上在做什么,这对我来说仍然是神奇的。

我的问题是,deriving引擎盖下发生了什么?另外,在Haskell源代码的GitHub上有一个地方可以看到实现吗?这也可能有所帮助。

1 个答案:

答案 0 :(得分:16)

GHC实际上只是编写您手动编写的同一个实例,如果将-ddump-deriv传递给编译器,则可以看到它生成的代码。例如:

Prelude> data Color = Red | Green | Blue deriving (Show)

==================== Derived instances ====================
Derived instances:
  instance Show Color where
    showsPrec _ Red = showString "Red"
    showsPrec _ Green = showString "Green"
    showsPrec _ Blue = showString "Blue"
    showList = showList__ (showsPrec 0)


Generic representation:

  Generated datatypes for meta-information:

  Representation types:

这里没有太大的魔力,Show只是一个非常机械的实现。在里面它查看数据构造函数的内部形式(GHC的源中的类型是DataConRep),它从翻译前端AST获得,然后查看前端源中提供的名称并添加一个新的Show实例这些名称的术语以及同时实现Show的任何嵌套类型。新的自动生成的类型类注册就像手工编写的类一样,就好像它是在当前模块中编写的一样。