在 Haskell 中,1 :| [2, 3, 4] 和 [1, 2, 3, 4] 有什么区别?

4

我正在学习 Haskell,它是最好的函数式编程语言之一。在学习列表时遇到了难题。我发现有两种方法可以编写列表-只需使用 [] 进行包装,或者使用 NonEmpty 列表。这些变体之间有什么区别,应该使用哪种更好,为什么?


2
简而言之,NonEmpty 将在编译时强制执行任何您使用的列表都不为空。如果您有一些函数无法处理空列表作为输入,那么这非常有用,并且比在运行时崩溃要好得多。但另一方面,在实践中,空列表经常出现并且通常不会造成任何问题 - 因此这取决于您的程序想要做什么。 - Robin Zigmond
1个回答

4

[1,2,3,4] 实际上是语法糖,表示为

Prelude> 1:2:3:4:[]
[1,2,3,4]

[]类型有两个数据构造器::[]。使用:将值添加到现有列表中。空列表[]是基本情况,因此为了能够创建有限列表,您必须用空列表终止“cons链”,就像上面的示例一样。

换句话说,虽然[1,2,3,4]是列表的一个有效示例,但[]也是一个有效的空列表。

顾名思义,NonEmpty不能是空的。它只有一个数据构造器::|。因此,您可以使用NonEmpty表示的最短列表是单例列表:

Prelude Data.List.NonEmpty> 1 :| []
1 :| []

:|的右侧确实可以接受空列表([]),但您必须为左侧提供一个值(在上面的示例中为1)。因此,NonEmpty列表始终至少包含一个元素。

这些属性在编译时得到保证,因此如果您需要非空列表,请使用NonEmpty,如果您需要可能为空的列表,请使用[]


1
有另一种非空列表的表述方式,对于某些目的可能更为合适。data NE a = Cons a (NE a) | Single a。这种表示方法每个列表可以少用一个单词,如果有许多这样的列表并且它们大多数只有一个元素,则可能很重要。 - dfeuer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接