以下是了解哈斯克尔的一个例子:
quicksort :: (Ord a) => [a] -> [a]
quicksort [] = []
quicksort (x:xs) =
let smallerSorted = quicksort [a | a <- xs, a <= x]
biggerSorted = quicksort [a | a <- xs, a > x]
in smallerSorted ++ [x] ++ biggerSorted
似乎列表每次递归迭代两次,每次列表理解一次。在编译器中是否存在一些优化它的魔力?如果没有,这怎么能解决?
编辑:如果这是一个真正的快速入口,我不在乎。忽略快速排序。 我的问题是关于两个列表推导的效率 ,以及如何修改这个特定的算法(快速排序与否),以避免每次递归迭代xs两次。 / p>
答案 0 :(得分:-1)
没有。截至目前,GHC 7.8.2还不够智能,无法从上面的quicksort
定义中找出巧妙的快速排序算法。通过将quicksort
定义为
import Data.List (partition)
quicksort :: (Ord a) => [a] -> [a]
quicksort [] = []
quicksort (x:xs) = let (psx1, psx2, psx3) = partition3 x (x:xs) in
quicksort psx1 ++ psx2 ++ quicksort psx3
partition3 _ [] = ([], [], [])
partition3 a (x:xs)
| a == x = (pxs1, x:pxs2, pxs3)
| a < x = (pxs1, pxs2, x:pxs3)
| a > x = (x:pxs1, pxs2, pxs3)
where (pxs1, pxs2, pxs3) = partition3 a xs
但您应该检查is it possible to do quicksort of a list with only one passing?,因为它比上述版本更有效。