我刚开始学习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上有一个地方可以看到实现吗?这也可能有所帮助。
答案 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的任何嵌套类型。新的自动生成的类型类注册就像手工编写的类一样,就好像它是在当前模块中编写的一样。