我正在学习 Haskell,它是最好的函数式编程语言之一。在学习列表时遇到了难题。我发现有两种方法可以编写列表-只需使用 []
进行包装,或者使用 NonEmpty
列表。这些变体之间有什么区别,应该使用哪种更好,为什么?
[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
,如果您需要可能为空的列表,请使用[]
。
data NE a = Cons a (NE a) | Single a
。这种表示方法每个列表可以少用一个单词,如果有许多这样的列表并且它们大多数只有一个元素,则可能很重要。 - dfeuer
NonEmpty
将在编译时强制执行任何您使用的列表都不为空。如果您有一些函数无法处理空列表作为输入,那么这非常有用,并且比在运行时崩溃要好得多。但另一方面,在实践中,空列表经常出现并且通常不会造成任何问题 - 因此这取决于您的程序想要做什么。 - Robin Zigmond