键入代数数据类型与通用类型
问题描述:
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(List t)”也可以被读为“C t E”?键入代数数据类型与通用类型
data NonEmptyList a = NEL a [a]
lst2 :: NonEmptyList = 2
为什么不能2被键入到a
作为t
键入到2在上述的情况下?
答
在第一种类型:
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
。