Haskell中的Data Type
Haskell当中的class可以类比为Java当中的interface,而Haskell当中的data则可以类比为Java当中,实现interface的class(当然,这样的类比只是从语法的角度上帮助理解,其背后的设计理念还是有本质的不同的)。
下面的代码定义一个data,叫做MyType
:
data MyType = Foo
上面的定义当中,Foo
是MyType
的constructor。Java当中每一个class有自己的constructor,但是constructor的名字要和class的名字保持一致,而在Haskell当中没有这种限制(并且设计理念也不同,不是一个概念,下面展开讲)。
下面是我们定义的MyType
的信息:
Prelude> :info MyType
data MyType = Foo -- Defined at <interactive>:1:1
Prelude> :info Int
data Int = GHC.Types.I# GHC.Prim.Int# -- Defined in ‘GHC.Types’
要注意的一点:Haskell要求类型的名称需要大写首字母,所以我们定义的type交做MyType
,不能起名叫myType
,这是Haskell的要求。
接下来我们看一下MyType
的具体定义:
data MyType = Foo
这个Foo
,被称为value constructor,它是一个函数:
Prelude> :t Foo
Foo :: MyType
可以看到Foo
这个函数不接收任何参数,返回类型为MyType
的数据。
我们试着使用Foo
函数来创建一个MyType
类型的数据:
Prelude> hahaha = Foo
Prelude> :info hahaha
hahaha :: MyType -- Defined at <interactive>:4:1
Prelude> :t hahaha
hahaha :: MyType
如上所示,我们调用Foo
函数,创建了一个MyType
类型的数据叫做hahaha
。
此外,Haskell还支持value constructor接收参数(可以类比为Java的class当中的constructor可以接收参数,是一个意思)。
比如我们可以定义一个叫做Book
的type,这个type里面包括Book
的一些信息,比如title
,author
,等等。我们定义Book
如下:
data Book = Book String String
如上所示,我们定义了Book
类型,然后定义了constructor叫做Book
(data的constructor允许和data自身的名字重名),这个constructor接收两个String类型的参数。
我们可以用:t
命令查询作为value constructor的Book
函数的定义:
Prelude> :t Book
Book :: String -> String -> Book
可以看到,这个叫做Book
的函数接收String
, String
参数,返回类型为Book
的数据(前面的Book
是函数,后面的返回值是Book
类型)。
我们使用看看:
mybook = Book "Charlotte's Web" "E. B. White"
如上所示,我们创建了一个mybook
数据,这本书的书名是Charlotte's Web
,作者是E. B. White
。
但是我们怎么查看mybook里面的书名和作者呢?
为了解决这个问题,我们可以创建两个函数,一个叫做title
,另一个叫做author
:
Prelude> title :: Book -> String; title (Book title _) = title
author :: Book -> String
Prelude> title :: Book -> String; author (Book _ author) = author
如上所示,我们定义了title
和author
两个函数,可以从Book
类型中的数据取得title
和author
信息:
最后我们使用看看这两个函数:
Prelude> author mybook
"E. B. White"
Prelude> title mybook
"Charlotte's Web"
Prelude>
如上所示,我们通过上面的函数取得了mybook
中的相关数据。
- 上一篇 编译器,LLVM与IR
- 下一篇 Haskell中的Record Syntax