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?
答案 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
。