如何对 Haskell 中的空向量进行模式匹配?
How to Pattern Match an Empty Vector in Haskell?
假设我想使用模式匹配实现列表的长度函数,那么我可以这样做:
length' :: (Num b) => [a] -> b
length' [] = 0
length' (_:xs) = 1 + length' xs
我可以用 Vector
做类似的事情吗?
vector
库的各种 Vector
类型是不透明类型,不公开其数据构造函数,因此您无法对它们进行模式匹配。
有很多解决方法,例如 ViewPatterns
(如 user2407038 的评论所述),但您肯定 不想 将这些与向量一起使用,因为您可能 放弃使用向量的优势 。
vector
库的亮点在于它是基于两个概念实现的:
- 向量具体化为 fixed-size、连续内存数组,它提供比 single-linked 列表或树更好的内存局部性;
- 根据可融合流实现了大量矢量操作,其操作编译为不为中间矢量分配内存的循环。
(1) 表示向量不具有自然的 "head" 和 "tail" 就像列表一样——列表是 字面上的 一对 a头和尾巴。如果您要使用某种视图模式在向量之上强加一个头+尾结构,您实际上会创建一个向量元素的 single-linked 列表,这可能会触发每个节点的内存分配视图类型。
如果您使用 ViewPatterns
将向量视为有效的单链表,为什么不直接将向量转换为列表呢?
无论如何,由于上面提到的设计要点,vector
你真的想尽可能坚持 the operations provided by the library itself,因为它们会利用库的性能特征。
我怀疑在许多情况下,测试向量的大小很可能不是最佳想法。例如,在这样的代码中:
example :: Vector something -> Vector somethingElse
example as
| Vector.null as = ...
| otherwise = ...
...我希望(但尚未验证!)这将强制向量 as
被具体化,以便我们可以测试它是否为空,如果可以消除测试或移动到其他地方,“...”位中的操作可能会与使用 example
的上下文融合。
假设我想使用模式匹配实现列表的长度函数,那么我可以这样做:
length' :: (Num b) => [a] -> b
length' [] = 0
length' (_:xs) = 1 + length' xs
我可以用 Vector
做类似的事情吗?
vector
库的各种 Vector
类型是不透明类型,不公开其数据构造函数,因此您无法对它们进行模式匹配。
有很多解决方法,例如 ViewPatterns
(如 user2407038 的评论所述),但您肯定 不想 将这些与向量一起使用,因为您可能 放弃使用向量的优势 。
vector
库的亮点在于它是基于两个概念实现的:
- 向量具体化为 fixed-size、连续内存数组,它提供比 single-linked 列表或树更好的内存局部性;
- 根据可融合流实现了大量矢量操作,其操作编译为不为中间矢量分配内存的循环。
(1) 表示向量不具有自然的 "head" 和 "tail" 就像列表一样——列表是 字面上的 一对 a头和尾巴。如果您要使用某种视图模式在向量之上强加一个头+尾结构,您实际上会创建一个向量元素的 single-linked 列表,这可能会触发每个节点的内存分配视图类型。
如果您使用 ViewPatterns
将向量视为有效的单链表,为什么不直接将向量转换为列表呢?
无论如何,由于上面提到的设计要点,vector
你真的想尽可能坚持 the operations provided by the library itself,因为它们会利用库的性能特征。
我怀疑在许多情况下,测试向量的大小很可能不是最佳想法。例如,在这样的代码中:
example :: Vector something -> Vector somethingElse
example as
| Vector.null as = ...
| otherwise = ...
...我希望(但尚未验证!)这将强制向量 as
被具体化,以便我们可以测试它是否为空,如果可以消除测试或移动到其他地方,“...”位中的操作可能会与使用 example
的上下文融合。