嵌套的列表
问题描述:
的自动打字,通过理查德·伯德的功能思考哈斯克尔工作,我碰到Haskell的类型系统的演示,我觉得百思不得其解(第44页):嵌套的列表
[ [], [[]], [[[]]] ] :: [[[[a]]]]
为了解释,让主列表的类型为
[b]
。第一个元素是 列表,所以b=[c]
。第二个元素是列表的列表,所以c=[d]
。该 第三个要素是列表的列表清单,所以d=[a]
不这种类型的签名表明主力名单的第一个元素类型[[[a]]]
?我不明白这是可能的。
答
让我们改写这个:
l = [l1, l2, l3]
where l1 = []
l2 = [[]]
l3 = [[[]]]
现在我们指定类型的变量:从头
l1 :: b
l2 :: b
l3 :: b
,因为他们都具有相同的类型,所以l
具有某种类型的[b]
。现在,更具体地说,
l1 :: [c]
l2 :: [[d]]
l3 :: [[[e]]]
以证明括号的数量。但这些还是要同类型b
,即实际上
l1 :: [[[e]]]
l2 :: [[[e]]]
l3 :: [[[e]]]
和
l = [ [] :: [[[e]]]
, [[]] :: [[[e]]]
, [[[]]] :: [[[e]]] ]
其作为一个整体具有类型[[[[e]]]]
。或者,如果你愿意,[[[[a]]]]
。
也许这一切都变得更清晰,如果你考虑更有趣的具体例子。以下是[Int]
列表:
[1,2,3]
[1]
[0]
[]
这些[[Int]]
列表:
[ [1,2], [1,2,3] ]
[ [1], [2] ]
[ [1], [] ]
[ [] ]
[ ]
这些都是[[[Int]]]
列表:
[ [[1]], [[2],[]], [[3],[],[]] ]
[ [[]], [[1]], [[2,3]] ]
[ [], [[]] ]
[ [[]] ]
[ ]
注意空单[]
能对所有类型。仅包含空列表的列表[[]]
对于[[Int]]
和[[[Int]]]
是可能的,并且包含仅具有空列表的列表需要双嵌套列表[[[Int]]]
。
如果我将一个整数放入这些嵌套列表(例如[[1],[[2]]]),编译器不再接受它。因此,他们怎么能有相同的类型? – planarian
编译器不再接受它,因为'[1]'和'[[2]]'不能有相同的类型(例如'[Int]'和'[[Int]]')。 OTOH,'[]'和'[[]]'都可以有'[[Int]]'类型,即列表的列表:前者是空列表(不包含列表),后者是_non-empty_列表,其中包含一个列表 - 虽然它不包含整数(但可能)。 – leftaroundabout
另请参阅我的编辑。 – leftaroundabout