call it同时提供ldd
和OrderedList
。
SortedList
的文档说:
SortedList
:保证对Sorted xs
进行排序。
xs
的文档说:
OrderedList
:保证订购Ordered xs
。
(我猜那些人应该分别说xs
和SortedList xs
。)
排序的列表和排序的列表有什么区别?
答案 0 :(得分:3)
tl; dr:我认为不建议使用const cat = this.format.header[0];
const count = this.format.header[1];
const obj = this.data.reduce((ac, o) => (ac[o[cat]] = o[count], ac), {});
,并且将其OrderedList
的实现移植到shrink
。
它们都定义为
SortedList
,但是newtype FooList a = Foo { getFoo :: [a] }
的选择不同。 (顺便说一句:这解释了文档为什么说Foo
和Sorted xs
而不是Ordered xs
和SortedList xs
的原因-这些是计算级术语,而不是类型级术语,因此该文档是正确的!)
除实例外,没有其他可用的特殊帮助器功能,因此,实例之间必须存在差异。两者都派生OrderedList xs
,所以在那里没有区别。
(Eq, Ord, Read, Show, Typeable)
有一个OrderedList
实例,而Functor
没有,但我认为SortedList
也不应有一个实例:它的OrderedList
不会保留订购文件所承诺的不变性。这个事实是我对是否弃用fmap
或SortedList
的绝望:使用不良的OrderedList
实例弃用一个实例,以便您只有一个向后不兼容的删除类型更改,而不是而不是弃用一个并从另一个中删除不良的Functor
实例。
Functor
实例几乎相同:
Arbitrary
因此,行为上的唯一区别是instance (Ord a, Arbitrary a) => Arbitrary (OrderedList a) where
arbitrary = Ordered `fmap` orderedList
shrink (Ordered xs) =
[ Ordered xs'
| xs' <- shrink xs
, sort xs' == xs'
]
orderedList :: (Ord a, Arbitrary a) => Gen [a]
orderedList = sort `fmap` arbitrary
instance (Arbitrary a, Ord a) => Arbitrary (SortedList a) where
arbitrary = fmap (Sorted . sort) arbitrary
shrink (Sorted xs) =
[ Sorted xs'
| xs' <- map sort (shrink xs)
]
进行相等检查,而OrderedList
不进行相等检查。这意味着SortedList
实例在SortedList
内部的工作量较少,但会产生更多重复的元素。如果相等检查比检查您当前试图寻找最小用例的属性便宜,那么shrink
选项是一个更好的权衡。在我看来,大多数情况下都是这种情况。
(几乎可以肯定,其中一个实现比其中任何一个都更有效的OrderedList
实现。)