用泛型类型键入代数数据类型

时间:2015-05-14 13:47:20

标签: haskell

data List t = E | C t (List t)
  deriving Show

lst1 :: List Int
lst1 = C 2 E

为什么t输入为2以防万一? 由于第一个后卫定义了" t = E"这是因为(List t)是允许的,所以" C t(列表t)"也可以阅读" C t E" ?

data NonEmptyList a = NEL a [a]
lst2 :: NonEmptyList = 2

为什么不能键入a,因为t在上述情况下输入为2?

1 个答案:

答案 0 :(得分:4)

在第一种类型中:

data List t = E | C t (List t)

t类型参数,必须以现有类型提供。 E不是类型,它是数据构造函数值构造函数C也是一个数据构造函数。他们有类型:

E :: List t
C :: t -> List t -> List t

您可以构建像

这样的值
> E :: List Int  -- Equivalent to []
E
> C 1 E :: List Int  -- Equivalent to [1]
C 1 E
> C 1 (C 2 E) :: List Int  -- Equivalent to [1, 2]
C 1 (C 2 E)

等等。您可以将E视为空列表[]C作为列表构造函数:,因此C 1 (C 2 (C 3 E))等同于1 : 2 : 3 : [][1, 2, 3]相同。

在第二种类型中:

data NonEmptyList a = NEL a [a]

你有数据构造函数

NEL :: a -> [a] -> NonEmptyList a

您可以构建像

这样的值
> NEL 1 [] :: NonEmptyList Int  -- Equivalent to [1]
NEL 1 []
> NEL 1 [2] :: NonEmptyList Int  -- Equivalent to [1, 2]

等等。此类型强制您始终至少有一个值,因此它不能为空。

当您撰写lst2 :: NonEmptyList = 2时,这是一个语法错误,很难猜出您的意思,但NonEmptyList Int的等效lst1 :: List Int将被写为NEL 2 [] :: NonEmptyList Int