术语一般(违背专门)中的问题表示该功能可以,只要它们是一种类型,是一个实例{{的项目进行排序1}}。
考虑一个最着名的haskell广告
Ord
上述实施不到位
我试图写一个就地版本。
就地快速进行快速排序很容易。通常,我们只需要一个可变数组,然后选择quicksort :: Ord a => [a] -> [a]
quicksort [] = []
quicksort (p:xs) = (quicksort lesser) ++ [p] ++ (quicksort greater)
where
lesser = filter (< p) xs
greater = filter (>= p) xs
我的实现是就地并且运行得很好,但我对它的类型签名不满意
Foreign.Marshal.Array
更确切地说,类型约束(Ord a, Storable a) => [a] -> IO [a]
让我烦恼。
显然,如果我们要对项目进行排序,则需要Storable a
约束,而Ord
则不需要。{
相比之下,经典快速排序或Storable
中sort
的类型签名为Data.List
。约束只是Ord a => [a] -> [a]
。
我没有找到摆脱额外约束的方法。
我搜索了Stackoverflow,发现了一些关于haskell的就地快速排序的问题,例如
How do you do an in-place quicksort in Haskell
Why is the minimalist, example Haskell quicksort not a "true" quicksort?
不幸的是,他们主要担心的是就地。这里给出的所有现场快速排序示例都有其他类型限制
例如,iqsort
given by klapaucius具有类型签名
Ord
有谁知道如何使用类型签名iqsort :: (Vector v a, Ord a) => v a -> v a
实现就地快速排序haskell功能?
我知道如何制作就地快速排序,但我不知道如何制作 general 。
答案 0 :(得分:5)
iqsort
实际上对我来说非常普遍。如果您查看Data.Vector.Generic haddocks,实际上您可以将该接口用于任何 a
!区别在于给定的函数是 more 泛型,因为它允许您选择未装箱的向量,当然这只适用于某些 a
。
以下是链接:http://hackage.haskell.org/packages/archive/vector/0.10.0.1/doc/html/Data-Vector-Generic.html
因此,如果选择要装箱的V,矢量约束就会消失。
答案 1 :(得分:3)
是的,这是可能的。 (尽管在Haskell中,只有在真正需要最佳性能的情况下才能使用这种命令式算法。)
我知道2种这样的算法:
(Introsort基本上是精简快速排序,具有 O(n log n)最坏情况的复杂性。)
我不确定MVector
,但对于MArray
,您不必担心其他约束MArray a e m
。他们在那里使类型更通用,而不是更少。像
qsort :: (MArray a e m, Ord e) => a Int e -> m ()
允许对不同的数组表示使用相同的算法。对于某些数据类型,您可以拥有该类型的专用数组,这些数组比通用数组更快,更紧凑。例如,如果要对8位整数进行排序,则unboxed arrays有一个专门的实例MArray IOUArray Int8 IO
。对于仅使用多态的这种数组,qsort
的特化是
qsort :: IOUArray Int Int8 -> IO ()
但您也有实例MArray IOArray e IO
的实例e
。通过qsort
使用IOArray
,您可以获得e
无约束的专业化:
qsort :: (Ord e) => IOArray Int e -> IO ()
此外,如果您使用STArray
和ST
monad,则可以使用相同的函数对数组进行就地排序,稍后将结果作为纯值获取,而不使用{{1 }}