Haskell中的Record Syntax

在前一篇文章中,给大家讲了Data Type,并且试着定义了一个Book类型:

data Book = Book String String

然后明白了等号右边的Book是等号左边的Book类型的constructor,也就是一是构造函数。这个函数接受两个String类型的参数,返回Book类型的数据。这一讲我们继续讲解数据类型。

首先我们继续看上面的Book的定义,我们的构造函数接受两个参数:StringString。我们自己知道,这两个String一个是书的标题,一个是书的作者。

然后我们在上一讲定义了两个函数来取得Book里面的这两个数据:

title :: Book -> String; title (Book title _) = title
author :: Book -> String; author (Book _ author) = author

但是上面的工作实在是太麻烦了:我们自己定义了数据类型Book,指定了数据参数的类型,却不能指定每个参数的名称来表达其含义,最后还要手工定义title和author函数来取得Book里面的数据。有没有简单一点的方案?

还好,Haskell的设计者也觉得上面这样太麻烦了,给我们一个省事的定义方法,帮我们完成以上内容。下面是具体的语法:

data Book = Book { title :: String, author :: String }

如上所示,我们在等号右边的Book这个value constructor的定义中使用这种大括号这样的语法来定义。这个语法叫做Record Syntax。

我们就指定了等号右边,Book构造函数接受的两个参数的名称,一个叫做title,另一个叫做author

语法就是上面那样,用大括号括起来。我们看看等号右边Book构造函数的定义:

Prelude> :t Book
Book :: String -> String -> Book

如上所示,等号右边Book构造函数接受两个String参数,返回类型为等号左边Book类型的数据。

我们使用一下试试看:

book = Book "Neuromancer" "Gibson"

如上所示,我们创建了一个book数据。我们试着取得book的title:

Prelude> title book
"Neuromancer"

可以看到,Haskell已经帮我们定义好了title函数,非常方便。此外,我们在定义数据的时候,通过Record Syntax,我们还多了一种定义方法:

Prelude> book2 = Book { author = "Masters of Doom", title = "Kushner" }

如上所示,我们可以使用大括号,里面明确指定哪个参数接受什么内容。实际上也算是一种syntax sugar了。

通过Record Syntax,我们在定义数据类型时省去了很多冗余的代码。